[sql] 쿼리 문자열에 대한 변수 선언

MS SQL Server 2005에서이 작업을 수행하는 방법이 있는지 궁금합니다.

  DECLARE @theDate varchar(60)
  SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

  SELECT    AdministratorCode,
            SUM(Total) as theTotal,
            SUM(WOD.Quantity) as theQty,
            AVG(Total) as avgTotal,
            (SELECT SUM(tblWOD.Amount)
                FROM tblWOD
                JOIN tblWO on tblWOD.OrderID = tblWO.ID
                WHERE tblWO.Approved = '1'
                AND tblWO.AdministratorCode = tblWO.AdministratorCode
                AND tblWO.OrderDate BETWEEN @theDate
            )
 ... etc

이것이 가능합니까?



답변

가능하지만 동적 SQL을 사용해야합니다. 계속하기 전에 동적 SQL의 저주와 축복을
읽는 것이 좋습니다 .

DECLARE @theDate varchar(60)
SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT AdministratorCode,
                   SUM(Total) as theTotal,
                   SUM(WOD.Quantity) as theQty,
                   AVG(Total) as avgTotal,
                  (SELECT SUM(tblWOD.Amount)
                     FROM tblWOD
                     JOIN tblWO on tblWOD.OrderID = tblWO.ID
                    WHERE tblWO.Approved = ''1''
                      AND tblWO.AdministratorCode = tblWO.AdministratorCode
                      AND tblWO.OrderDate BETWEEN '+ @theDate +')'

EXEC(@SQL)

동적 SQL은 실행되기 전에 문자열로 구성된 SQL 문입니다. 따라서 일반적인 문자열 연결이 발생합니다. 다음과 같이 허용되지 않는 SQL 구문을 수행하려면 동적 SQL이 필요합니다.

  • IN 절에 대해 쉼표로 구분 된 값 목록을 나타내는 단일 매개 변수
  • 값과 SQL 구문을 모두 나타내는 변수 (IE : 제공 한 예)

EXEC sp_executesql bind / preparedstatement 매개 변수를 사용할 수 있으므로 SQL 인젝션 공격을 위해 작은 따옴표 등을 이스케이프 처리 할 필요가 없습니다.


답변

DECLARE @theDate DATETIME
SET @theDate = '2010-01-01'

그런 다음이 논리를 사용하도록 쿼리를 변경합니다.

AND
(
    tblWO.OrderDate > DATEADD(MILLISECOND, -1, @theDate)
    AND tblWO.OrderDate < DATEADD(DAY, 1, @theDate)
)


답변

EXEC 사용

다음 예제를 사용하여 SQL 문을 작성할 수 있습니다.

DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = ' + @city
EXEC (@sqlCommand)

sp_executesql 사용

이 접근 방식을 사용하면 쿼리에 전달되는 데이터 값이 올바른 데이터 유형인지 확인하고 더 많은 따옴표를 사용할 수 없습니다.

DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = 'London'
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = @city'
EXECUTE sp_executesql @sqlCommand, N'@city nvarchar(75)', @city = @city

참고


답변

나는 최고 등급의 답변 The Curse and Blessings of Dynamic SQL에 링크 된 기사 에서 저자가 대답은 동적 SQL을 사용하지 않는 것이라고 언급했습니다. 이것을 보려면 거의 끝까지 스크롤하십시오.

기사에서 “올바른 방법은 사용자 정의 함수 또는 저장 프로 시저가있는 테이블에 목록을 압축 해제하는 것입니다.”

물론 목록이 테이블에 있으면 조인을 사용할 수 있습니다. 최고 평점 답변에 직접 댓글을 달 수 없어서이 댓글을 추가했습니다.


답변