[SQL] SQL 서버 : 어떻게 저장 프로 시저의 매개 변수로 데이터베이스 이름을 얻을 수 있습니다
SQLSQL 서버 : 어떻게 저장 프로 시저의 매개 변수로 데이터베이스 이름을 얻을 수 있습니다
나는 sys.tables 테이블을 조회하는 간단한 저장 프로 시저를 만들려고 해요.
CREATE PROCEDURE dbo.test
@dbname NVARCHAR(255),
@col NVARCHAR(255)
AS
SET NOCOUNT ON
SET XACT_ABORT ON
USE @dbname
SELECT TOP 100 *
FROM sys.tables
WHERE name = @col
GO
내가 사용 @dbname 후 GO를 넣어해야하지만이 절차의 작성을 종료 원인이 작동하지 않는 것? 어떻게 사용자가이 시저의 매개 변수로 데이터베이스 이름을 지정할 수 있도록하는 것이이 과정에이 데이터베이스 selction를 넣을 수 있습니다?
해결법
-
==============================
1.이 작업을 수행하는 적어도 두 가지 방법이 있습니다 :
이 작업을 수행하는 적어도 두 가지 방법이 있습니다 :
물론, 예를 들어, 당신은 할 수
set @sql='select * from '+@dbname+'.sys.tables';
.
. 해상도 연산자는 사용 문을 사용하지 않고 다른 데이터베이스에 쿼리 객체로 할 수 있습니다. sproc에 임의의 데이터베이스를 사용할 수 있도록하는 것이 바람직 할 수있는 매우, 매우 드문 경우가 있습니다. 제 생각에는, 유일한 허용 사용은 코드 생성기, 또는 시간의 필요한 정보를 미리 알 수없는 데이터베이스 분석 도구의 일종이다.
당신이 밖으로 업데이트 턴은 유일하게 확실한 방법으로 동적 SQL을 떠나, 저장 프로 시저에서 사용할 수 없습니다. 그래도, 내가 사용하는 것이 좋습니다 것
select top 100 * from db_name.dbo.table_name
오히려 사용하는 것보다.
-
==============================
2.@var 전달 된 이름과 일치하는 저장 프로 시저에 대한 SQL 서버 외모 - 당신은 (즉,하지 EXEC (@var) 괄호없이) EXEC @var 사용하는 경우. 이 세 부분의 이름을 사용할 수 있습니다.
@var 전달 된 이름과 일치하는 저장 프로 시저에 대한 SQL 서버 외모 - 당신은 (즉,하지 EXEC (@var) 괄호없이) EXEC @var 사용하는 경우. 이 세 부분의 이름을 사용할 수 있습니다.
sys.sp_executesql은 세 부분으로 된 이름으로 호출하면 컨텍스트가 호출하는 데이터베이스로 설정됩니다.
그래서 당신은 아래와 같이 제로 SQL 주입 위험이 작업을 수행 할 수 있습니다.
CREATE PROCEDURE dbo.test @dbname SYSNAME, @col SYSNAME AS SET NOCOUNT, XACT_ABORT ON; DECLARE @db_sp_executesql NVARCHAR(300) = QUOTENAME(@dbname) + '.sys.sp_executesql' EXEC @db_sp_executesql N' SELECT TOP 100 * FROM sys.columns WHERE name = @col', N'@col sysname', @col = @col
심지어 위의 경우에하는 것은 내가 아직도 여기로 안전한 방식이 동적 SQL을 사용할 수 있도록 완벽하게 가능하다고 주장 줄 수 없었습니다.
CREATE PROCEDURE dbo.test @dbname SYSNAME, /*Use Correct Datatypes for identifiers*/ @col SYSNAME AS SET NOCOUNT ON SET XACT_ABORT ON IF DB_ID(@dbname) IS NULL /*Validate the database name exists*/ BEGIN RAISERROR('Invalid Database Name passed',16,1) RETURN END DECLARE @dynsql nvarchar(max) /*Use QUOTENAME to correctly escape any special characters*/ SET @dynsql = N'USE '+ QUOTENAME(@dbname) + N' SELECT TOP 100 * FROM sys.tables WHERE name = @col' /*Use sp_executesql to leave the WHERE clause parameterised*/ EXEC sp_executesql @dynsql, N'@col sysname', @col = @col
-
==============================
3.이 작업을 수행 할 수있는 유일한 방법은 강력하지만 위험 동적 SQL을 사용하는 것입니다.
이 작업을 수행 할 수있는 유일한 방법은 강력하지만 위험 동적 SQL을 사용하는 것입니다.
앞서이 문서를 읽어보십시오.
-
==============================
4.같은 말에 대한 다른 방법은 시스템 저장 프로 시저를 사용하는 것입니다.
같은 말에 대한 다른 방법은 시스템 저장 프로 시저를 사용하는 것입니다.
여러 데이터베이스에서 실행 - 참조 SQL 프로 시저 (들)을 저장.
프로 시저 이름이 "SP_"로 시작하면, 마스터 DB에 후는 다음과 같이 호출 할 수 있습니다, sys.sp_MS_MarkSystemObject 표시 :
Exec somedb.dbo.Test; Exec anotherdb.dbo.Test;
또는과 같습니다 :
Declare @Proc_Name sysname; Set @Proc_Name = 'somedb.dbo.Test'; Exec @Proc_Name;
매개 변수도 사용할 수 있습니다.
이 기술을 사용하면 시스템 데이터베이스에 'SP_'접두사와 퍼팅 코드를 사용이 필요합니다. 그 오프셋은 동적 SQL을 사용하지 않을 경우, 그것은 당신의 선택입니다.
from https://stackoverflow.com/questions/3943823/sql-server-how-to-get-a-database-name-as-a-parameter-in-a-stored-procedure by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 중복이 SQL과 테이블에 위에 각 그룹에서 3 값을 선택하는 방법 [중복] (0) | 2020.07.01 |
---|---|
[SQL] SQL 쿼리에서 역 중복 제거 (0) | 2020.07.01 |
[SQL] 다른 열 그룹화 다른 칼럼의 최대 값에 기초 얻기 [중복] (0) | 2020.07.01 |
[SQL] 어떻게 SQL Server의 공휴일을 결정합니까? (0) | 2020.07.01 |
[SQL] 이노 디비에서 MySQL을 LIKE '% 문자열 %'쿼리를 최적화 (0) | 2020.07.01 |