2012-03-23 130 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