Sql-Server
嘗試根據日期限制儲存過程結果
我有以下儲存過程:
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 注入的角度來看,這要安全得多。對於我的其他觀點的一些閱讀: