2009-12-16 5 views
0

이 쿼리는 @SearchCriteria와 나머지 쿼리를 varchar로 분할해야한다는 것을 알 수 있습니다. 만약 내가 강제로, 구문은 잘 작동하지만 여분의 '대체 TSQL

도와 드릴까요?

ALTER PROCEDURE [dbo].[sp_rte_GetRateList] 
(
    @TenantID  INT, 
    @CustomerID  BIGINT = -1, 
    @SearchCriteria VARCHAR(64) = '', 
    @SortBy   VARCHAR(16) = '', 
    @SortType  VARCHAR(16) = '', 
    @Debug   BIT = 0 
) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql nvarchar(4000), 
      @paramlist nvarchar(4000) 

    IF (@SearchCriteria = '') 
    BEGIN 
     SELECT @sql = 'SELECT r.TenantID, r.RateID, r.RateGUID, r.RateCode, r.RateName, r.RateDescription, r.ValidityUTCDate, r.CreatedUTCTimeStamp, 
          r.CreatedIP, r.CreatedBy, r.LastModifiedUTCTimeStamp, r.LastModifiedIP, r.LastModifiedBy, r.IsActive, 
          c.CustomerID, c.CustomerName, rt.RateTypeID, rt.RateTypeName, s.SupplierID, s.SupplierName, r.FixedLineAmount, r.MobileAmount, r.DataAmount, r.OtherAmount, 
          (r.FixedLineAmount + r.MobileAmount + r.DataAmount + r.OtherAmount) AS TotalAmount, 
          r.CreatedUTCTimeSTamp, 
          STUFF((SELECT '', '' + ct.CustomerTypeName 
            FROM glb_CustomerTypes ct JOIN glb_CustomerCustomerTypes cct ON cct.CustomerTypeID = ct.CustomerTypeID 
            WHERE cct.CustomerID = C.CustomerID 
            GROUP BY ct.CustomerTypeName FOR XML PATH('''')), 1, 2, '''') AS CustomerTypeName 
         FROM dbo.rte_Rates r 
           INNER JOIN dbo.rte_RateTypes rt ON r.RateTypeID = rt.RateTypeID 
           INNER JOIN dbo.glb_Suppliers s ON r.SupplierID = s.SupplierID 
           INNER JOIN dbo.glb_Customers c ON r.CustomerID = c.CustomerID 
           INNER JOIN dbo.glb_Addresses a ON c.CustomerID = a.CustomerID 
           INNER JOIN dbo.glb_AddressTypes at ON a.AddressTypeID = at.AddressTypeID 
         WHERE at.AddressTypeCode = ''GLB_ADT_PHYSCLDDRS'' AND 
           r.TenantID = @xTenantID AND 
           rt.TenantID = @xTenantID AND 
           s.TenantID = @xTenantID AND 
           r.IsActive = 1 AND 
           rt.IsActive = 1 AND 
           c.IsActive = 1 AND 
           c.CustomerID = @xCustomerID ' 
    END 
    ELSE 
    BEGIN 
     SELECT @sql = 'SELECT r.TenantID, r.RateID, r.RateGUID, r.RateCode, r.RateName, r.RateDescription, r.ValidityUTCDate, r.CreatedUTCTimeStamp, 
          r.CreatedIP, r.CreatedBy, r.LastModifiedUTCTimeStamp, r.LastModifiedIP, r.LastModifiedBy, r.IsActive, 
          c.CustomerID, c.CustomerName, rt.RateTypeID, rt.RateTypeName, s.SupplierID, s.SupplierName, r.FixedLineAmount, r.MobileAmount, r.DataAmount, r.OtherAmount, 
          (r.FixedLineAmount + r.MobileAmount + r.DataAmount + r.OtherAmount) AS TotalAmount, 
          r.CreatedUTCTimeSTamp, 
          STUFF((SELECT '', '' + ct.CustomerTypeName 
            FROM glb_CustomerTypes ct JOIN glb_CustomerCustomerTypes cct ON cct.CustomerTypeID = ct.CustomerTypeID 
            WHERE cct.CustomerID = C.CustomerID 
            GROUP BY ct.CustomerTypeName FOR XML PATH('''')), 1, 2, '''') AS CustomerTypeName 
         FROM dbo.rte_Rates r 
           INNER JOIN dbo.rte_RateTypes rt ON r.RateTypeID = rt.RateTypeID 
           INNER JOIN dbo.glb_Suppliers s ON r.SupplierID = s.SupplierID 
           INNER JOIN dbo.glb_Customers c ON r.CustomerID = c.CustomerID 
           INNER JOIN dbo.glb_Addresses a ON c.CustomerID = a.CustomerID 
           INNER JOIN dbo.glb_AddressTypes at ON a.AddressTypeID = at.AddressTypeID 
         WHERE at.AddressTypeCode = ''GLB_ADT_PHYSCLDDRS'' AND 
           r.TenantID = @xTenantID AND 
           rt.TenantID = @xTenantID AND 
           s.TenantID = @xTenantID AND 
           r.IsActive = 1 AND 
           rt.IsActive = 1 AND 
           c.IsActive = 1 AND 
           c.CustomerID = @xCustomerID AND 
           (r.RateCode LIKE ''%' + @SearchCriteria + '%'' OR 
           r.RateName LIKE ''%' + @SearchCriteria + '%'' OR 
           rt.RateTypeName LIKE ''%' + @SearchCriteria + '%'' OR 
           r.RateDescription LIKE ''%' + @SearchCriteria + '%'' OR 
           s.SupplierCode LIKE ''%' + @SearchCriteria + '%'' OR 
           s.SupplierName LIKE ''%' + @SearchCriteria + '%'' OR 
           c.CustomerCode LIKE ''%' + @SearchCriteria + '%'' OR 
           c.CustomerName LIKE ''%' + @SearchCriteria + '%'' OR 
           c.CustomerDescription LIKE ''%' + @SearchCriteria + '%'') '      
    END 

    SELECT @sql = @sql + 'ORDER BY ' + @SortBy + ' ' + @SortType 

    IF (@Debug = 1) PRINT @sql 

    SELECT @paramlist = '@xTenantID INT, @xCustomerID BIGINT' 

    EXEC sp_executesql @sql, @paramlist, @TenantID, @CustomerID 
END 

답변

2

당신은 @SearchCriteria의 모든 따옴표를 두 배로 수 있지만, 그 SQL 주입의 모든 형태에 대해 당신을 보호하지 않습니다 - 당신은 멀리 동적 SQL에서 얻어서 할 수 있습니다.

나는이 특정 문제에 대해 동적 SQL이 필요하다고 100 % 확신하지 않습니다.

1

난 당신이 NULL로 @SearchCriteria를 초기화 더 나을 거라고 생각 : 당신이 동적 SQL은 당신이했던 방법은 설치 이유를 얻을

ALTER PROCEDURE [dbo].[sp_rte_GetRateList] 
( ... 
    @SearchCriteria  VARCHAR(64), --inits as NULL 
    .... 
) 

    IF @SearchCriteria IS NOT NULL 
    BEGIN 

     SET @SearchCriteria = REPLACE(@SearchCriteria, '''', '''''') 
     ... 
    END 
    ELSE 
     ... 

- 내가 발견에 @SearchCriteria이없는 paramlist 따라서 @SearchCriteria의 param 인스턴스를 정의 할 필요가 없습니다. 동일한 테이블에서 2 개 이상의 열이있을 때 전체 텍스트 검색을 고려할 수 있습니다. 더 빠르고 복잡하지는 않습니다.