我必须修改一些似乎无法正常工作的 SQL 代码。
SQL 代码对我来说看起来很糟糕,但它在大多数情况下都有效。
假设我们有多个名称相似的供应商:Microsoft、Microsoft Corp 和 Microsoft, Inc 等。
所有查询返回都是 Microsoft,即使现有代码包含该行PRI_VENDOR_NAME like '%' @PRI_VENDOR_NAME '%'
(或者,至少看起来确实如此)。
我似乎无法检查代码是否正常工作,因为它是一大段看起来令人讨厌的代码,它将数据附加到一个长字符串以执行。
当前程序:(准备尖叫)
ALTER PROCEDURE [dbo].[GetSignalMasterByFilter]
(
@planner varchar(50),
@reorder int,
@release int,
@CMTTED varchar(50),
@partid varchar(50),
@global_short_dt int,
@PRI_VENDOR_NAME varchar(50)
)
AS
BEGIN
DECLARE @Filter nvarchar(4000)
set @Filter = ' '
if @planner <> ''
begin
set @Filter = ' and planner in(' + @planner + ')'
end
if @reorder = 1
begin
set @Filter = rtrim(@Filter) + ' and (REORDER_50 = ' + char(39) + 'Y' + char(39) + ' ) '
end
if @reorder = 2
begin
set @Filter = rtrim(@Filter) + ' and (REORDER_30 = ' + char(39) + 'Y' + char(39) + ' ) '
end
if @reorder = 3
begin
set @Filter = rtrim(@Filter) + ' and (REORDER_POINT = ' + char(39) + 'Y' + char(39) + ' ) '
end
--if @noaction = 1
--begin
--set @Filter = rtrim(@Filter) + ' and reorder in (' + char(39) + 'Excess' + char(39) + ',' + char(39) + 'Watch' + char(39) + ')'
--end
if @release = 1
begin
set @Filter = rtrim(@Filter) + ' and (RELEASE_50 = ' + char(39) + 'Y' + char(39) + ' ) '
end
if @release = 2
begin
set @Filter = rtrim(@Filter) + ' and (RELEASE_30 = ' + char(39) + 'Y' + char(39) + ' ) '
end
if @release = 3
begin
set @Filter = rtrim(@Filter) + ' and (RELEASE_POINT = ' + char(39) + 'Y' + char(39) + ' ) '
end
if @CMTTED <> 'View ALL'
begin
set @Filter = rtrim(@Filter) + ' and CMTTED > ' + char(39) + '0' + char(39) + ' and isnumeric(CMTTED) = 1 '
end
if @global_short_dt = 1
begin
set @Filter = rtrim(@Filter) + ' and (global_short_dt is not null or cast(CMTTED as int) > cast(ON_HAND as int)) '
end
if @global_short_dt = 2
begin
set @Filter = rtrim(@Filter) + ' and (global_short_dt is not null or cast(CMTTED as int) > cast(ON_HAND as int)) AND ((cast(QTY_IN_STATUS as float) + cast(ON_ORDER as float) + cast(ON_HAND as float)) < cast(CMTTED as int)) '
end
if @partid <> ''
begin
set @Filter = rtrim(@Filter) + ' and partid like(' + char(39) + @partid + '%' + char(39) + ')'
end
if @PRI_VENDOR_NAME <> ''
begin
set @Filter = rtrim(@Filter) + ' and PRI_VENDOR_NAME like(' + char(39) + @PRI_VENDOR_NAME + '%' + char(39) + ')'
end
DECLARE @sql nvarchar(4000)
SET @sql = '
SELECT DISTINCT PRIMARY_VENDOR,case when PRI_VENDOR_NAME is null then PRIMARY_VENDOR else PRIMARY_VENDOR +' + char(39) + ' - ' + char(39) + '+ PRI_VENDOR_NAME end as PRI_VENDOR_NAME
FROM SignalReportView WHERE PRIMARY_VENDOR is not null ' + rtrim(@filter) + ' order by PRI_VENDOR_NAME'
--print @sql
EXEC sp_executesql @sql
end
我想做的是用我在下面开始的东西替换那个讨厌的字符串变量,但是 SQL 不是我的强项,所以它还没有完全返回任何数据:
MY PROCEDURE VERSION:不返回数据,但看起来更干净,将来更容易维护。
ALTER PROCEDURE GetSignalMasterByFilter2(
@planner varchar(50),
@reorder int,
@release int,
@CMTTED varchar(50),
@partid varchar(50),
@global_short_dt int,
@PRI_VENDOR_NAME varchar(50)
) as begin
SELECT DISTINCT
PRIMARY_VENDOR,
case when PRI_VENDOR_NAME is null then PRIMARY_VENDOR else PRIMARY_VENDOR +' - '+ PRI_VENDOR_NAME end as PRI_VENDOR_NAME
FROM
SignalReportView
WHERE
(PRIMARY_VENDOR is not null)
and (
ISNULL(@planner,0)=0 or
planner in (@planner))
and (
(@reorder=1 and REORDER_50='Y') or
(@reorder=2 and REORDER_30='Y') or
(@reorder=3 and REORDER_POINT='Y') or
(1=1)
)
and (
(@release=1 and RELEASE_50='Y') or
(@release=2 and RELEASE_30='Y') or
(@release=3 and RELEASE_POINT='Y') or
(1=1)
)
and (
(@CMTTED='View ALL') or
(0<CMTTED and ISNUMERIC(CMTTED)=1)
)
and (
(
(@global_short_dt=1) and
(
(GLOBAL_SHORT_DT is not null) or
(CAST(ON_HAND as int) < CAST(CMTTED as int))
)
) or
(1=1)
)
and (
(
(@global_short_dt=2) and
(
(GLOBAL_SHORT_DT is not null) or
(
(CAST(ON_HAND as int) < CAST(CMTTED as int)) and
((CAST(QTY_IN_STATUS as float) + CAST(ON_ORDER as float) + CAST(ON_HAND as float)) < CAST(CMTTED as int))
)
)
) or
(1=1)
)
and (
ISNULL(@partid,0)=0 or
(PARTID like '%'+@partid+'%')
)
and (
ISNULL(@PRI_VENDOR_NAME,0)=0 or
(PRI_VENDOR_NAME like '%'+@PRI_VENDOR_NAME+'%')
)
ORDER BY PRI_VENDOR_NAME
end
所以,我的问题是:
将原始脚本重写为其他开发人员将来更容易维护的版本是否是个好主意?
如果否,有人能发现为什么现有的 SQL 没有返回所有供应商吗?
如果是,有人可以指导我设计我的版本吗?它目前不起作用 - 可能是因为我有一些逻辑错误。此外,这些(1=1)
条款不适合我,但我不知道如何绕过它们。由于我的程序不返回任何数据,所以我现在不能使用它。
我很抱歉没有发布表结构,但它们都相当大,并且上面的存储过程查询了一个看起来更糟糕的视图(我什至无法遵循)。