2012-03-23 152 views
0

當談到SQL仍然學習繩索​​時,我不是最好的。 我有我的SQL服務器管理器中的存儲過程2008年SQL Case語句錯誤

USE [ShaftData] 
GO 
/****** Object: StoredProcedure [dbo].[GetSalesBuyers] Script Date: 03/23/2012 08:13:17 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[GetSalesBuyers] 
@Cdisc varchar(255), 
@bcs varchar(255), 
@From date, 
@Too date 
AS 
SELECT i.Acct, 
    i.Name, 
    i.Document, 
    i.Part, 
    i.Qty, 
    i.Unit, 
    dbo.NEWPareto.Pareto, 
    i.pg, 
    dbo.MyPgTable.PgName, 
    i.[DateTime], 
    i.BinSeqNo, 
    i.cdisc, 
    i.bcs 

FROM 
OPENQUERY(SACBAUTO, 'SELECT dbo.iHeads.acct, 
          dbo.iHeads.name, 
          dbo.iLines.Document, 
          dbo.iLines.Part, 
          dbo.iLines.Pg, 
          dbo.iLines.Qty, 
          dbo.iLines.unit, 
          dbo.iHeads.[DateTime], 
          dbo.iLines.BinSeqNo, 
          dbo.Customer.cdisc, 
          dbo.Customer.Bcs 
        FROM Autopart.dbo.iheads INNER JOIN Autopart.dbo.iLines ON 
        Autopart.dbo.Iheads.document = autopart.dbo.iLines.document 
        INNER JOIN Autopart.dbo.Customer ON Autopart.dbo.iheads.acct 
        = Autopart.dbo.customer.keycode 
        GROUP By dbo.iHeads.acct, 
          dbo.iHeads.name, 
          dbo.iLines.Document, 
          dbo.iLines.Part, 
          dbo.iLines.Pg, 
          dbo.iLines.Qty, 
          dbo.iLines.unit, 
          dbo.iHeads.[DateTime], 
          dbo.iLines.BinSeqNo, 
          dbo.Customer.cdisc, 
          dbo.Customer.bcs 
         ') i 
left JOIN 
dbo.NEWPareto 
ON 
i.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NEWPareto.Part 
left JOIN 
dbo.MyPgTable 
ON 
i.pg collate SQL_Latin1_General_CP1_CI_AS = dbo.MyPgTable.[pGroup] 

WHERE 
(i.[DateTime] BETWEEN @From AND @Too) 
AND i.cdisc = @Cdisc 
AND i.bcs != @bcs 
AND i.pg != '60' 
AND i.pg != '61' 
AND i.pg != '62' 

GROUP BY i.Acct, 
    i.Name, 
    i.Document, 
    i.Part, 
    i.Qty, 
    i.Unit, 
    dbo.NEWPareto.Pareto, 
    i.pg, 
    dbo.MyPgTable.PgName, 
    i.[DateTime], 
    i.BinSeqNo, 
    i.cdisc, 
    i.bcs 

我需要的是一個條件的where子句。特別是這一行「AND i.bcs!= @bcs」。

如果我將空字符串傳遞給我的參數,我希望該行存在並在where子句中運行,會發生什麼情況。

否則如果我不傳遞任何東西(空),我需要該行不存在(不運行)。

我玩過,但所有即時獲取是紅線,無處不在,當我嘗試創建。

有沒有人有想法?我接近我的方法嗎?可以做到嗎?或者有沒有一種簡單的模式方式,即時通訊查看。 非常感謝

回答

2

可選參數構造是這樣的:

WHERE (@bcs is null OR i.bcs != @bcs) 

如果您發送空的每行被選中;如果您發送其他內容,則只會選擇不匹配的行。你不應該擔心性能,因爲Sql Server對於常量表達式非常好,如果它評估爲1,它將被抑制。

USE [ShaftData] 
GO 
/****** Object: StoredProcedure [dbo].[GetSalesBuyers] Script Date: 03/23/2012 08:13:17 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[GetSalesBuyers] 
@Cdisc varchar(255), 
@bcs varchar(255), 
@From date, 
@Too date 
AS 
SELECT i.Acct, 
    i.Name, 
    i.Document, 
    i.Part, 
    i.Qty, 
    i.Unit, 
    dbo.NEWPareto.Pareto, 
    i.pg, 
    dbo.MyPgTable.PgName, 
    i.[DateTime], 
    i.BinSeqNo, 
    i.cdisc, 
    i.bcs 

FROM 
OPENQUERY(SACBAUTO, 'SELECT dbo.iHeads.acct, 
          dbo.iHeads.name, 
          dbo.iLines.Document, 
          dbo.iLines.Part, 
          dbo.iLines.Pg, 
          dbo.iLines.Qty, 
          dbo.iLines.unit, 
          dbo.iHeads.[DateTime], 
          dbo.iLines.BinSeqNo, 
          dbo.Customer.cdisc, 
          dbo.Customer.Bcs 
        FROM Autopart.dbo.iheads INNER JOIN Autopart.dbo.iLines ON 
        Autopart.dbo.Iheads.document = autopart.dbo.iLines.document 
        INNER JOIN Autopart.dbo.Customer ON Autopart.dbo.iheads.acct 
        = Autopart.dbo.customer.keycode 
        GROUP By dbo.iHeads.acct, 
          dbo.iHeads.name, 
          dbo.iLines.Document, 
          dbo.iLines.Part, 
          dbo.iLines.Pg, 
          dbo.iLines.Qty, 
          dbo.iLines.unit, 
          dbo.iHeads.[DateTime], 
          dbo.iLines.BinSeqNo, 
          dbo.Customer.cdisc, 
          dbo.Customer.bcs 
         ') i 
left JOIN 
dbo.NEWPareto 
ON 
i.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NEWPareto.Part 
left JOIN 
dbo.MyPgTable 
ON 
i.pg collate SQL_Latin1_General_CP1_CI_AS = dbo.MyPgTable.[pGroup] 

WHERE 
(i.[DateTime] BETWEEN @From AND @Too) 
AND i.cdisc = @Cdisc 
AND (@bcs is null OR i.bcs != @bcs) 
AND i.pg != '60' 
AND i.pg != '61' 
AND i.pg != '62' 

GROUP BY i.Acct, 
    i.Name, 
    i.Document, 
    i.Part, 
    i.Qty, 
    i.Unit, 
    dbo.NEWPareto.Pareto, 
    i.pg, 
    dbo.MyPgTable.PgName, 
    i.[DateTime], 
    i.BinSeqNo, 
    i.cdisc, 
    i.bcs 
+0

感謝您的帖子,你可以將它應用於我的代碼,ive有一個去,但即時獲取紅色下劃線告訴我什麼是做錯了 – lemunk 2012-03-23 08:46:09

+0

我編輯了我的答案。如果您發現錯誤,請發佈第一條錯誤。 – 2012-03-23 08:51:42

1

我知道你可以做到這一點(正是你想要的是使用動態sql)的唯一途徑,就是說,它不漂亮。你把你的整個過程放在一個字符串變量中,然後根據需要進行構建。然後最後執行它。我會稍微更新一下這篇文章。

看看這個link關於如何正常的語法。

不要評判我,我不喜歡編寫這通常

但是這是你要找的

IF (ISNULL(@bcs,0) <> 0) 
     SET @SQL = @SQL + ' AND i.bcs != '[email protected] + CHAR(13) 

你更新PROC的一部分。

USE [ShaftData] 
GO 
/****** Object: StoredProcedure [dbo].[GetSalesBuyers] Script Date: 03/23/2012 08:13:17 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[GetSalesBuyers] 
@Cdisc varchar(255), 
@bcs varchar(255), 
@From date, 
@Too date 
AS 

DECLARE @SQL NVARCHAR(MAX) 

SET @SQL = ' SELECT i.Acct, i.Name, i.Document, i.Part, i.Qty, i.Unit, dbo.NEWPareto.Pareto, i.pg,' + CHAR(13) 
SET @SQL = @SQL + ' dbo.MyPgTable.PgName,i.[DateTime],i.BinSeqNo,i.cdisc,i.bcs' + CHAR(13) 
SET @SQL = @SQL + ' FROM ' + CHAR(13) 
SET @SQL = @SQL + ' OPENQUERY(SACBAUTO, ''SELECT dbo.iHeads.acct, dbo.iHeads.name,dbo.iLines.Document,dbo.iLines.Part, ' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.Pg,dbo.iLines.Qty,dbo.iLines.unit,dbo.iHeads.[DateTime], dbo.iLines.BinSeqNo, ' + CHAR(13) 
SET @SQL = @SQL + '       dbo.Customer.cdisc,dbo.Customer.Bcs ' + CHAR(13) 
SET @SQL = @SQL + '      FROM Autopart.dbo.iheads INNER JOIN Autopart.dbo.iLines ON ' + CHAR(13) 
SET @SQL = @SQL + '      Autopart.dbo.Iheads.document = autopart.dbo.iLines.document' + CHAR(13) 
SET @SQL = @SQL + '      INNER JOIN Autopart.dbo.Customer ON Autopart.dbo.iheads.acct ' + CHAR(13) 
SET @SQL = @SQL + '      = Autopart.dbo.customer.keycode' + CHAR(13) 
SET @SQL = @SQL + '      GROUP By dbo.iHeads.acct,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iHeads.name,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.Document,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.Part,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.Pg,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.Qty,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.unit,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iHeads.[DateTime],' + CHAR(13) 
SET @SQL = @SQL + '       dbo.iLines.BinSeqNo,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.Customer.cdisc,' + CHAR(13) 
SET @SQL = @SQL + '       dbo.Customer.bcs' + CHAR(13) 
SET @SQL = @SQL + '      '') i' + CHAR(13) 
SET @SQL = @SQL + 'left JOIN' + CHAR(13) 
SET @SQL = @SQL + 'dbo.NEWPareto' + CHAR(13) 
SET @SQL = @SQL + 'ON ' + CHAR(13) 
SET @SQL = @SQL + 'i.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NEWPareto.Part ' + CHAR(13) 
SET @SQL = @SQL + 'left JOIN' + CHAR(13) 
SET @SQL = @SQL + 'dbo.MyPgTable ' + CHAR(13) 
SET @SQL = @SQL + 'ON ' + CHAR(13) 
SET @SQL = @SQL + ' i.pg collate SQL_Latin1_General_CP1_CI_AS = dbo.MyPgTable.[pGroup]' + CHAR(13) 
SET @SQL = @SQL + 'WHERE' + CHAR(13) 
SET @SQL = @SQL + ' (i.[DateTime] BETWEEN ''[email protected]+'' AND ''[email protected]+'') ' + CHAR(13) 
SET @SQL = @SQL + ' AND i.cdisc = '+ @Cdisc + CHAR(13) 


IF (ISNULL(@bcs,0) <> 0) 
    SET @SQL = @SQL + ' AND i.bcs != '[email protected] + CHAR(13) 


SET @SQL = @SQL + ' AND i.pg != ''60''' + CHAR(13) 
SET @SQL = @SQL + ' AND i.pg != ''61''' + CHAR(13) 
SET @SQL = @SQL + ' AND i.pg != ''62''' + CHAR(13) 

SET @SQL = @SQL + ' GROUP BY i.Acct,' + CHAR(13) 
SET @SQL = @SQL + ' i.Name, ' + CHAR(13) 
SET @SQL = @SQL + ' i.Document, ' + CHAR(13) 
SET @SQL = @SQL + ' i.Part, ' + CHAR(13) 
SET @SQL = @SQL + ' i.Qty, ' + CHAR(13) 
SET @SQL = @SQL + ' i.Unit, ' + CHAR(13) 
SET @SQL = @SQL + ' dbo.NEWPareto.Pareto, ' + CHAR(13) 
SET @SQL = @SQL + ' i.pg,' + CHAR(13) 
SET @SQL = @SQL + ' dbo.MyPgTable.PgName, ' + CHAR(13) 
SET @SQL = @SQL + ' i.[DateTime],' + CHAR(13) 
SET @SQL = @SQL + ' i.BinSeqNo,' + CHAR(13) 
SET @SQL = @SQL + ' i.cdisc,' + CHAR(13) 
SET @SQL = @SQL + ' i.bcs' + CHAR(13) 

EXEC(@SQL)

+0

哎喲,我簡單的方法是複製過程中沒有一行,然後有條件存在我的代碼中調用iether一個。但是,我們都知道重複某件事從來不是一個好方法。 – lemunk 2012-03-23 08:41:24

+0

好的,我更喜歡@NikolaMarkovinović的回答。實際上並不知道你可以在where子句中使用可選參數。似乎iv'e也被教育過... – 2012-03-23 08:44:26

+0

也CHAR(13)是一個新的字符,我曾經在一個公司工作與1000遺留的SQL procs,都像這樣:|,它幫助閱讀proc裏面SQL profiler – 2012-03-23 08:46:51