要写个存储过程,因为字段是动态的,里面除了嵌套其他存储过程,还要执行用字符串组合的一段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')
SQLEXEC

解决方案 »

  1.   

    最好的方法是不要用select ... into  语句
    而是动态拼接出create table语句和insert... select语句
      

  2.   

    分钟级的delay客户都能忍受,搂主真实幸福
      

  3.   

    写漏了,我把这个存储过程加入作业,大概半个小时执行一次,但是现在经常把ItemCSC这个表给删了
    我在怀疑我的思路是不是一开始就错了,请教下大家有没有更好的解决方法我又想了方法,就是一直检测##Reuslt创建完没,创建完了才执行后面的操作,但是还是失败了Exec (@SQLStatement)While Not Exists(Select Name from Tempdb..sysObjects where Name='##Reuslt')
     Begin
    WAITFOR DELAY '00:00:01'
     EndWAITFOR DELAY '00:02:00'
    IF Exists (select Name from SysObjects where Name='ItemCSC') Drop Table ItemCSC
    Exec ('Select * Into ItemCSC from ##Reuslt')
      

  4.   

    单就解决你的问题而言,实际想执行的是数据库中的会话通信,可以先建立全局临时表或实体表,在去表中读更新状态
    WHILE @B
    BEGIN
    WAITFOR('00:10.00')
    IF NOT EXISTS(SELECT 1 FROM TB_TEMP_LOCK)
    BEGIN
    @B=FALSE
    END
    END
      

  5.   

    不直接用Select ... Into 
    那就得用Drop Table ... 然后再 Create table
      

  6.   

    IF Exists (select Name from Tempdb..SysObjects where Name='##Reuslt') Drop Table ##GarProdInqCSC这句是笔误?drop再create一般应该没有问题
      

  7.   


    嗯 是笔误,写好的存储过程是正确的
    IF Exists (select Name from Tempdb..SysObjects where Name='##Reuslt') Drop Table ##Reuslt
      

  8.   

    是不是这句报错?改成如下试下:
    IF Exists (select Name from Tempdb..SysObjects where Name='##Reuslt') 
      exec('Drop Table ##Reuslt ')
      

  9.   

    另外,你确定你的实际是这么使用的?
    对于全局临时表 ##Reuslt ,任何进程都可以删除的,如果其他进程删除了,就可能出现问题除非你的表名也是动态的。
      

  10.   

    如下:
    declare @Tablename nvarchar(300)
    set @Tablename = '##' + HOST_NAME() + replace(replace(replace(replace(convert(varchar(23),GETDATE(),121),'.',''),':',''),' ',''),'-','')
    IF Exists (select Name from Tempdb..SysObjects where Name=@Tablename) 
    exec('Drop Table ' + @Tablename)
    Select @SQLStatement=@SQLStatement+' Into ' + @Tablename + ' ' + 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 ' + @Tablename)
      

  11.   

    不是其他存储过程,而是调用同一个存储过程的多个进程互相影响永久表ItemCSC 也会出现这个情况,需要暂时去掉这段代码证实是否这个问题,然后考虑如何修改
      

  12.   

    调试时只有一个进程当然没有问题你的写法太不规范,存储过程业务中应该很少drop table,包括永久表和临时表
    最后长远的写法还是只有2楼说的
      

  13.   

    try this,exec(@SQLStatement)while object_id('tempdb..##Reuslt') is null
    begin
      if object_id('tempdb..##Reuslt') is not null
        break
    endif exists(select 1 from sysObjects where Name='ItemCSC') 
      drop table ItemCSCexec('Select * Into ItemCSC from ##Reuslt')
      

  14.   

    try this,exec(@SQLStatement)while object_id('tempdb..##Reuslt') is null
    begin
      if object_id('tempdb..##Reuslt') is not null
        break
    endif exists(select 1 from sysObjects where Name='ItemCSC') 
      drop table ItemCSCexec('if object_id(''tempdb..##Reuslt'') is not null begin select * Into ItemCSC from ##Reuslt end')
      

  15.   

    修改了一下上面的:
    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秒,稍后再试
    endif exists(select 1 from sysObjects where Name='ItemCSC') 
      drop table ItemCSCexec('if object_id(''tempdb..##Reuslt'') is not null begin select * Into ItemCSC from ##Reuslt end')
      

  16.   

    其实我觉得,这个问题和写一般的程序很相似。都存在一个进程间的协调问题,都是一步一步,上一步做完后,再做下一步。一般在程序中,可以通过信号量、互斥体、全局变量来实现。但在sql server中无法实现这种全局变量的效果,是在不行,你可以在系统中创建一个表,把状态insert 到表中,然后你在运行下一步之前,读这个表,判断一下状态,如果是这个状态,就执行下一步,如果不是,那么再等待一会,但是频繁的while循环,这样会消耗cpu时间,可以休息个10秒钟,再判断。