ALTER procedure [dbo].[PSI]
@`PartNo` nvarchar (50),
@Customer nvarchar (50),
@Date1 Date,
@Date2 Date
AS
Begin
declare @Qty int,
@i int,
@max_i int,
@b nvarchar(15),
@j int,
@max_j int
IF EXISTS (SELECT * FROM tempdb.sys.sysobjects WHERE name like '#Test%')
DROP TABLE #Test
create table #Test(
IDX int identity(1,1),
Item nvarchar(50)
)
insert into #Test(Item) select distinct Name_Customer from Master_Products where Name like '%' + @PartNo + '%' and Customer like '%' + @Customer + '%'
set @i=0
set @max_i=DATEDIFF(day, @Date1, @Date2)
Set @Qty=2
DECLARE @SQL NVARCHAR(200)
DECLARE @SQL1 NVARCHAR(200)
DECLARE @x int
DECLARE @y int
DECLARE @z int
while @i<=@max_i
begin
set @j=1
set @max_j=(SELECT MAX(IDX) FROM #Test)
Set @b=Dateadd(day,@i,@Date1)
Set @SQL='alter table #Test
add [' + cast(@b AS NVARCHAR(10)) + ']' + + 'int'
exec [sp_executesql] @sql WITH RECOMPILE
while @j<=@max_j
Begin
Set @x=(SELECT SUM(Qty)
FROM Planning_Stock_Balance
WHERE DateAjust<=@b and (select top 1 name from Master_Products where Name=Planning_Stock_Balance.PartNo) =(select item from #Test where IDX=@j))
Set @y=(SELECT SUM(OKQTY) FROM Injection_Daily_Result WHERE PRODATE<=@b and (select top 1 name from Master_Products where Name=Injection_Daily_Result.PartNo)=(select item from #Test where IDX=@j))
Set @z=(SELECT SUM(Qty) FROM Sales_PO WHERE DeliDate<=@b and (select top 1 name from Master_Products where Name=Sales_PO.ItemCode)=(select item from #Test where IDX=@j))
Set @SQL1 ='update #Test
set [' + cast(@b AS NVARCHAR(10)) + ']=' + CAST(isnull(@x,0)+isnull(@y,0)-isnull(@z,0)
AS NVARCHAR(10))
+ ' where idx =' + cast(@j as NVARCHAR(10)) +''
exec [sp_executesql] @sql1 WITH RECOMPILE
SET @j=@j+1
end
SET @i=@i+1
end
Select * from #Test
OPTION ( OPTIMIZE FOR UNKNOWN )
-- where Item like '%' + @PartNo + '%' and (select top 1 Customer from Master_Products where Name=Item) like '%' + @Customer +'%'
IF OBJECT_ID(N'tempdb..#Test', N'U') IS NOT NULL
drop table #Test
End
答案 0 :(得分:1)
这段代码非常晦涩,不清楚您要实现的目标。
一些提示:
使用有意义的变量名,例如@stock_balance
而不是@x
,@y
等变量名。这缺少命名约定不仅使局外人也难以遵循该代码。
通常,在设计合理的关系数据库中,您将使用 ID 或某些唯一键来处理客户,而不像您在此处那样使用名称:>
and Customer like '%' + @Customer + '%'
那是不安全:只要想想如果您有多个同名或同名客户,会发生什么情况。
更不用说这样的where
子句将无法使用索引,前提是您甚至拥有一个。
如果在运行过程时显示执行计划,它应该向您显示花费很长时间的部分(或者您可以在代码中添加一些print getdate()
)。 / p>
动态SQL不仅危险,而且很少有道理。必须有一个更好的方法。
您在过程中使用了许多表,这些表的结构是未知的。您应该做的是发布这些表的结构,显示一些示例数据,并提供预期结果的示例。