Sql-Server

嘗試根據日期限制儲存過程結果

  • January 23, 2018

我有以下儲存過程:

ALTER PROCEDURE [dbo].[TW_spRPTAllReceiverInventory] 
@SiteId varchar(50), 
@ReceiverId int,
@UserName varchar(50)

AS

BEGIN

DECLARE @SQL varchar(8000), 
       @Index int, 
       @Value varchar(500), 
       @Source varchar(100), 
       @tmp DATETIME

SELECT @Index = CHARINDEX('Initial Catalog=', ConnectionString) + 16, 
      @Value = ConnectionString
FROM   CustomerSetting
WHERE  SiteId = @SiteId

SET @Source = '[' 
              + SUBSTRING(@Value , @Index, CHARINDEX(';', @Value, @Index) - @Index) 
              + ']'

SET @SQL = 'SELECT R.SiteId, L.* FROM ' 
          + @Source 
          + '.[dbo].[vwReceiver] R JOIN ' 
          + @Source 
          + '.[dbo].[vwInventory] L ON R.ReceiverId = L.ReceiverId
       WHERE R.ReceiverId = ' 
          + CAST(@ReceiverId as varchar) 
          + ' AND L.ModifiedUserName = ' 
          + Cast(@UserName as varchar)

EXEC(@SQL)

END

我需要做的是根據其中一列(列是ModifiedDate,它是一個 DateTime 列)過濾結果,以僅顯示今天創建的記錄。我該如何做到這一點?

使用QUOTENAME()around@source而不是手動在它周圍拍打方括號。您還可以確保數據庫名稱存在,以防有人將動態 SQL 漏洞利用到您的CustomerSetting表中。另外請始終指定一個長度,varchar但最好正確參數化它們。

假設您總是想要一天,這是一種非常靈活的方法。您可以選擇傳入特定日期;如果你不這樣做,它會假設今天。如果您想要超過一天,可以很容易地擴展它以適應一個範圍。

ALTER PROCEDURE dbo.TW_spRPTAllReceiverInventory
 @SiteId     varchar(50), 
 @ReceiverId int,
 @UserName   varchar(50),
 @date       date = NULL
AS
BEGIN
 DECLARE @sql    nvarchar(max), 
         @exec   nvarchar(4000),
         @Source sysname;

 SELECT @Source = SUBSTRING(v, i, CHARINDEX(';', v, i) - i),
        @date   = CONVERT(date, COALESCE(@date, GETDATE()))
   FROM ( SELECT i = CHARINDEX('Initial Catalog=', ConnectionString) + 16, 
                 v = ConnectionString
            FROM   dbo.CustomerSetting -- added dbo prefix here
            WHERE  SiteId = @SiteId) AS x;

 SET @exec = QUOTENAME(@Source) + N'.sys.sp_executesql';

 IF @date IS NOT NULL AND DB_ID(@Source) > 4
 BEGIN
   SET @sql = N'SELECT R.SiteId, L.* FROM [dbo].[vwReceiver] R 
                JOIN [dbo].[vwInventory] L 
                ON R.ReceiverId = L.ReceiverId
                WHERE R.ReceiverId = @ReceiverId
                  AND L.ModifiedUserName = @UserName
                  AND L.ModifiedDate >= @date
                  AND L.ModifiedDate <  DATEADD(DAY, 1, @date);'; 

   EXEC @exec @sql, -- this will execute in the context of @Source
        N'@ReceiverId int, @UserName varchar(50), @date date',
        @ReceiverId, @UserName, @date;

 END
END

從 SQL 注入的角度來看,這要安全得多。對於我的其他觀點的一些閱讀:

引用自:https://dba.stackexchange.com/questions/195963