首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

如何在一个存储过程内使用多个EXEC和时效性有关问题

2013-11-02 
怎么在一个存储过程内使用多个EXEC和时效性问题要写个存储过程,因为字段是动态的,里面除了嵌套其他存储过

怎么在一个存储过程内使用多个EXEC和时效性问题
要写个存储过程,因为字段是动态的,里面除了嵌套其他存储过程,还要执行用字符串组合的一段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秒钟,再判断。

热点排行