要写个存储过程,因为字段是动态的,里面除了嵌套其他存储过程,还要执行用字符串组合的一段SQL语句
比如今天有50个字段,明天说不定就是52个字段,后天就是57个字段,这些字段都记录在MstGridCol表里面,而后面的表链接都存入GridSQLStatement里面
Declare @SQLStatement VarChar(Max)
/*这个初始化一个物品信息表,大概5-6秒左右*/
Exec SP_Initialize '##ItemInfo',' and SellMonth in (Select Distinct Top 2 Month(SellDate) from ItemSellInfo Order By SellDate Desc)'
/*这里从MstGridCol表中取字段并组合,比如组合后是
Select 'Sell' As ProcessClass,b.ItemClass,a.ItemName,c.PayState
*/
Set @SQLStatement='Select 'Sell' As ProcessClass'
Select @SQLStatement=@SQLStatement+','+DataField from MstGridCol where Formname='ItemSellInfo' And GridName='Detail2'
/*这里从GridSQLStatement 取form之后的表组合字符串,比如组合后是
from ItemCSC a inner join MstItemClass on a.ItemClass=b.ItemClass Left join ItemPayInfo c on a.PayMonth=c.PayMonth where a.ItemType='Online'
*/
IF Exists (select Name from Tempdb..SysObjects where Name='##Reuslt') Drop Table ##GarProdInqCSC
Select @SQLStatement=@SQLStatement+' Into ##Reuslt '+SQLStatement from GridSQLStatement where Formname='ItemSellInfo' And GridName='Detail2'
/*组合后执行,由于表数量过多,数据量大,所以组合后执行时间大概为60秒以上*/
Exec (@SQLStatement)
IF Exists (select Name from SysObjects where Name='ItemCSC') Drop Table ItemCSC
Exec ('Select * Into ItemCSC from ##Reuslt')
现在问题就来了,SQL实行过程中提示找不到##Reuslt,我猜测是组合字符串执行那段运行时间中,SQL没等这段执行完
Exec (@SQLStatement)
就执行了
Exec ('Select * Into ItemCSC from ##Reuslt')
我不知道怎么让SQL能等做完上一步的EXEC工作后才执行下一步的EXEC
我在中间加了个
Exec (@SQLStatement)
WAITFOR DELAY '00:02:00'
IF Exists (select Name from SysObjects where Name='ItemCSC') Drop Table ItemCSC
Exec ('Select * Into ItemCSC from ##Reuslt')
SQL EXEC
------解决方案--------------------
最好的方法是不要用select ... into 语句
而是动态拼接出create table语句和insert... select语句
------解决方案--------------------
单就解决你的问题而言,实际想执行的是数据库中的会话通信,可以先建立全局临时表或实体表,在去表中读更新状态
WHILE @B
BEGIN
WAITFOR('00:10.00')
IF NOT EXISTS(SELECT 1 FROM TB_TEMP_LOCK)
BEGIN
@B=FALSE
END
END
------解决方案--------------------
调试时只有一个进程当然没有问题
你的写法太不规范,存储过程业务中应该很少drop table,包括永久表和临时表
最后长远的写法还是只有2楼说的
------解决方案--------------------
try this,
exec(@SQLStatement)
while object_id('tempdb..##Reuslt') is null
begin
if object_id('tempdb..##Reuslt') is not null
break
end
if exists(select 1 from sysObjects where Name='ItemCSC')
drop table ItemCSC
exec('if object_id(''tempdb..##Reuslt'') is not null begin select * Into ItemCSC from ##Reuslt end')
------解决方案--------------------
修改了一下上面的:
exec(@SQLStatement)
while object_id('tempdb..##Reuslt') is null
begin
if object_id('tempdb..##Reuslt') is not null
break
else
WAITFOR DELAY '00:00:10' --等待10秒,稍后再试
end
if exists(select 1 from sysObjects where Name='ItemCSC')
drop table ItemCSC
exec('if object_id(''tempdb..##Reuslt'') is not null begin select * Into ItemCSC from ##Reuslt end')
------解决方案--------------------
其实我觉得,这个问题和写一般的程序很相似。
都存在一个进程间的协调问题,都是一步一步,上一步做完后,再做下一步。
一般在程序中,可以通过信号量、互斥体、全局变量来实现。
但在sql server中无法实现这种全局变量的效果,是在不行,你可以在系统中创建一个表,把状态insert 到表中,然后你在运行下一步之前,读这个表,判断一下状态,如果是这个状态,就执行下一步,如果不是,那么再等待一会,但是频繁的while循环,这样会消耗cpu时间,可以休息个10秒钟,再判断。