2009-07-01 60 views
2

我有一個呼叫數據記錄表,其中每個呼叫都有一個呼叫數據,其中一個字段是我們在查詢數據庫時使用的CallerId。「數組參數」TSQL

我們使用下面的TSQL來模擬數組參數,這是要走還是走的路?

ALTER PROCEDURE [dbo].[spStudio_Get_Smdr] 
    @beginTime INT, 
    @endTime INT, 
    @subscribers VARCHAR(MAX) = NULL, 
    @exchanges VARCHAR(MAX) = '1:', 
    @beginDateValue int, 
    @endDateValue int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @exch TABLE(Item Varchar(50)) 
    INSERT INTO @exch 
    SELECT Item FROM [SplitDelimitedVarChar] (@exchanges, '|') ORDER BY Item 


    DECLARE @subs TABLE(Item Varchar(19)) 
    INSERT INTO @subs 
    SELECT Item FROM [SplitDelimitedVarChar] (@subscribers, '|') ORDER BY Item 

    SELECT 
     ,[Level] 
     ,[Timestamp] 
     ,[EndYear] 
     ,[EndDate] 
     ,[EndTime] 
     ,[CallingNumber] 
     ,[DialledNumber] 
     ..more fields between 
     ,[DateValue] 
     ,[TimeValue] 
    FROM [SmdrFormat] AS S 
    WHERE 
     (S.[DateValue] BETWEEN @beginDateValue AND @endDateValue) 
    AND 
     (S.[TimeValue] BETWEEN @beginTime AND @endTime) 
    AND 
     EXISTS(SELECT [Item] FROM @exch WHERE [Item] = S.[Level]) 
    AND 
     (@subscribers IS NULL OR (EXISTS(SELECT [Item] FROM @subs WHERE [Item] = S.[CallingNumber] 
              OR [Item] = S.[DialledNumber]))) 

END 

我使用表變量來存儲我從和分裂臨時表|分隔的字符串,我們作爲參數傳入。 SplitDelimitedVarChar SQL函數將一個VarChar分割並返回一個Table變量。時間和日期值以整數形式存儲。

對WHERE子句中使用的所有字段進行索引。

當分隔字符串參數很短但變大時(upp爲幾個由|分隔的數百個字符串),這可以正常工作,執行查詢需要相當長的時間。

因爲我明顯不是SQL大師,我覺得有可能有​​人能告訴我,如果我真的很糟糕att SQL或只是得到了一些部分錯誤?任何建議表示讚賞

在此先感謝 約翰

回答

1

在2008年,使用表值參數

+0

對於SQL Server 2008,請參閱http://stackoverflow.com/questions/43249/t-sql-stored-procedure-that-accepts-multiple-id-values。 – 2009-07-01 17:15:45

0

這裏我嘗試在重構它:

ALTER PROCEDURE [dbo].[spStudio_Get_Smdr] 
    @beginTime INT, 
    @endTime INT, 
    @subscribers VARCHAR(MAX) = NULL, 
    @exchanges VARCHAR(MAX) = '1:', 
    @beginDateValue int, 
    @endDateValue int 
AS 
SET NOCOUNT ON; 


IF @subscribers IS NULL 
BEGIN 
    SELECT 
     [Level] 
      ,[Timestamp] 
      ,[EndYear] 
      ,[EndDate] 
      ,[EndTime] 
      ,[CallingNumber] 
      ,[DialledNumber] 
      --..more fields between 
      ,[DateValue] 
      ,[TimeValue] 
     FROM [SmdrFormat] AS S 
     WHERE (S.[DateValue] BETWEEN @beginDateValue AND @endDateValue) 
      AND (S.[TimeValue] BETWEEN @beginTime AND @endTime) 
      AND EXISTS (SELECT [Item] FROM [SplitDelimitedVarChar] (@exchanges, '|') WHERE S.[Level]=[Item]) 

END 
ELSE 
BEGIN 

    SELECT 
     [Level] 
      ,[Timestamp] 
      ,[EndYear] 
      ,[EndDate] 
      ,[EndTime] 
      ,[CallingNumber] 
      ,[DialledNumber] 
      --..more fields between 
      ,[DateValue] 
      ,[TimeValue] 
     FROM [SmdrFormat] AS S 
     WHERE (S.[DateValue] BETWEEN @beginDateValue AND @endDateValue) 
      AND (S.[TimeValue] BETWEEN @beginTime AND @endTime) 
      AND EXISTS (SELECT [Item] FROM [SplitDelimitedVarChar] (@exchanges, '|') WHERE S.[Level]=[Item]) 
      AND EXISTS (SELECT [Item] FROM [SplitDelimitedVarChar] (@subscribers, '|') WHERE S.[Level]=[Item] OR S.[DialledNumber]=u2.[Item]) 
END 

RETURN 0 
GO 

另外,請確保您的拆分功能是最快的,see my code here

0

關於如何將大量數據傳遞給存儲過程的幾個詳細示例,請考慮this article