Проблема SQL Case Statement - PullRequest
       22

Проблема SQL Case Statement

0 голосов
/ 23 марта 2012

я не лучший, когда дело доходит до SQL, все еще учась. У меня есть хранимая процедура в диспетчере SQL Server 2008.

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.

Иначе, ЕСЛИ я ничего не передаю (null), мне нужно, чтобы строка не существовала (не запускалась).

Я играл, но все, что я получаю, это красные линии везде, когда я пытаюсь создать.

У кого-нибудь есть идея? я близок в своей методологии? это можно сделать? или есть простой способ, который я пропускаю. Большое спасибо

Ответы [ 2 ]

2 голосов
/ 23 марта 2012

Необязательные параметры построены так:

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

Если вы отправляете ноль, то выбирается каждая строка; если вы отправите что-нибудь еще, будут выбраны только несовпадающие строки. Вы не должны беспокоиться о производительности, потому что Sql Server очень хорош с константными выражениями, и если он оценивается как один, он будет подавлен.

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
1 голос
/ 23 марта 2012

Единственный способ, которым я знаю о том, что вы можете сделать это (именно то, что вы хотите, это использовать динамический sql), как говорится, это не красиво Вы помещаете весь процесс в строковую переменную, а затем создаете его по мере необходимости. затем выполните его в конце. Я обновлю этот пост с примером чуть позже.

посмотрите на эту ссылку о том, как синтаксис выглядит нормально.

Не суди меня, я обычно так не пишу

но это та часть, которую вы ищете

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

Ваш обновленный процесс.

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 ''+@From+'' AND ''+@Too+'') ' + CHAR(13)
SET @SQL = @SQL + ' AND i.cdisc = '+ @Cdisc  + CHAR(13)


IF (ISNULL(@bcs,0) <> 0)
   SET @SQL = @SQL + ' AND i.bcs != '+@bcs + 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)

...