set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
goALTER function [dbo].[insertdataout](@add_op char(1),@bh int,@mch nchar(255),@leixing int)
returns int
as
begin
declare @i int,@ivar char(2),@strSQL nvarchar(1000),@monthname nchar(9) 
set @monthname='dataout'
set @i=0
while @i<12
begin
set @monthname=left(@monthname,7)
    set @ivar=datename(month,dateadd(month,@i,getdate()))--这样的操作会把返回过去
if @ivar<='12'
begin
set @monthname=rtrim(ltrim(+@monthname))+@ivar
if @add_op=1
begin
set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select @bh,@mch,bmbh,bmmch,@leixing from bm'
end
if @add_op=2
begin
set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select spbh,spmch,@bh,@mch,@leixing from sp'
end
exec sp_executesql @strSQL 
end
if @ivar='12'
begin--不要把当前月以前的数据进行更新,中更新到12月份数据,由于上面的操作会返回到当前月以前月的数据
return 1--用goto returnlab更好好返回操作的标识状态
end
set @i=@i+1 
endreturn 1
end消息 557,级别 16,状态 2,过程 adddata,第 18 行
只有函数和扩展存储过程才能从函数内部执行。set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER procedure [dbo].[adddata] @add_op char(1),@bh int,@mch nchar(255),@leixing int as
begin
declare @monthname nchar(9),@insertdataoutreturn int 
set @monthname='dataout'
--1更新基础数据
--a.更新商品表
if @add_op='1'
begin
if not exists (select spbh from sp where @bh=spbh)
begin
insert into sp(spid,spbh,spmch,leixing,[datetime0],[datetime1])   select max(spid)+1 as spid,@bh,@mch,@leixing,getdate(),getdate() from sp
select @insertdataoutreturn=dbo.insertdataout(@add_op,@bh,@mch,@leixing)--从当月开始,调用增加dataxx表中数据的条目
end
else
begin
raiserror('已存在此商品.',16,1);
return --已存在此商品添加失败
end
end
--b.更新部门表5
else if @add_op='2'
begin
if not exists (select bmbh from bm where @bh=bmbh)
begin
insert into bm(bmid,bmbh,bmmch,[datetime0],[datetime1])   select max(bmid)+1 as bmid,@bh,@mch,getdate(),getdate() from bm 
select @insertdataoutreturn=dbo.insertdataout(@add_op,@bh,@mch,@leixing)--从当月开始,调用增加dataxx表中数据的条目
end
else
begin
raiserror('已存在此部门.',16,1);
return --已存在此部门添加失败
end
end
else
return--c.更新部门商品表
/*insert into bmsp(spbh,bmbh) select distinct a.spbh ,b.bmbh from sp a,bm b,bmsp c --由于在这多了一个表所以造成查询时间长
where a.spbh not in  (select spbh from bmsp) or  b.bmbh not in  (select bmbh from bmsp) order by spbh,bmbh*/------------最好是这样就可以了,不然按上面查询的时间长(上面多了一个表)
/*insert into bmsp(spbh,bmbh) select   a.spbh ,b.bmbh from sp a,bm b
where (a.spbh not in  (select spbh from bmsp) and a.status<>'停售') or  (b.bmbh not in  (select bmbh from bmsp) and b.status<>'停用')
每增加一个商品,就往bmsp里表插入数据(同时这个商品的品种的装态为可用的,每增加一个商品,就往bmsp里表插入数据(同时这个商品的品种的装态为可用的)
这样的话操作插入数据的时间更短*/
--2更实际操作要用月份的部门商品
/*declare @i int,@ivar char(2),@strSQL nvarchar(1000)
set @i=0
while @i<12
begin
set @monthname=left(@monthname,7)
    set @ivar=datename(month,dateadd(month,@i,getdate()))--这样的操作会把返回过去
if @ivar<='12'
begin
set @monthname=rtrim(ltrim(+@monthname))+@ivar
set @strSQL='insert into ['+@monthname+'](spbh,bmbh) select  spbh,bmbh from sp,bm
where spbh not in  (select spbh from '+@monthname+') or bmbh not in (select bmbh from '+@monthname+') order by spbh,bmbh'
exec sp_executesql @strSQL 
end
if @ivar='12'
begin--不要把当前月以前的数据进行更新,中更新到12月份数据,由于上面的操作会返回到当前月以前月的数据
return --用goto returnlab更好好返回操作的标识状态
end
set @i=@i+1 
end
*/
return --返回消息提示更新商品资料或部门资料数据操作成功end
--出入参数:入操作标识(增加商品还是增加品种),编号,名称。出参数添加商品,部门失败,操作成功

解决方案 »

  1.   

    可关键我想简化化代码在函数中执行sqlstr啊,我换了一种方式
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go
    ALTER procedure [dbo].[adddata] @add_op char(1),@bh int,@mch nchar(255),@leixing int as
    begin
    declare @monthname nchar(9) 
    set @monthname='dataout'
    --1更新基础数据
    --a.更新商品表
    if @add_op='1'
    begin
    if not exists (select spbh from sp where @bh=spbh)
    begin
    insert into sp(spid,spbh,spmch,leixing,[datetime0],[datetime1])   select max(spid)+1 as spid,@bh,@mch,@leixing,getdate(),getdate() from sp
    --select @insertdataoutreturn=dbo.insertdataout(@add_op,@bh,@mch,@leixing)--从当月开始,调用增加dataxx表中数据的条目
    end
    else
    begin
    raiserror('已存在此商品.',16,1);
    return --已存在此商品添加失败
    end
    end
    --b.更新部门表5
    else if @add_op='2'
    begin
    if not exists (select bmbh from bm where @bh=bmbh)
    begin
    insert into bm(bmid,bmbh,bmmch,[datetime0],[datetime1])   select max(bmid)+1 as bmid,@bh,@mch,getdate(),getdate() from bm 
    --select @insertdataoutreturn=dbo.insertdataout(@add_op,@bh,@mch,@leixing)--从当月开始,调用增加dataxx表中数据的条目
    end
    else
    begin
    raiserror('已存在此部门.',16,1);
    return --已存在此部门添加失败
    end
    end
    else
    return--c.更新部门商品表
    /*insert into bmsp(spbh,bmbh) select distinct a.spbh ,b.bmbh from sp a,bm b,bmsp c --由于在这多了一个表所以造成查询时间长
    where a.spbh not in  (select spbh from bmsp) or  b.bmbh not in  (select bmbh from bmsp) order by spbh,bmbh*/------------最好是这样就可以了,不然按上面查询的时间长(上面多了一个表)
    /*insert into bmsp(spbh,bmbh) select   a.spbh ,b.bmbh from sp a,bm b
    where (a.spbh not in  (select spbh from bmsp) and a.status<>'停售') or  (b.bmbh not in  (select bmbh from bmsp) and b.status<>'停用')
    每增加一个商品,就往bmsp里表插入数据(同时这个商品的品种的装态为可用的,每增加一个商品,就往bmsp里表插入数据(同时这个商品的品种的装态为可用的)
    这样的话操作插入数据的时间更短*/
    --2更实际操作要用月份的部门商品
    /*declare @i int,@ivar char(2),@strSQL nvarchar(1000)
    set @i=0
    while @i<12
    begin
    set @monthname=left(@monthname,7)
        set @ivar=datename(month,dateadd(month,@i,getdate()))--这样的操作会把返回过去
    if @ivar<='12'
    begin
    set @monthname=rtrim(ltrim(+@monthname))+@ivar
    set @strSQL='insert into ['+@monthname+'](spbh,bmbh) select  spbh,bmbh from sp,bm
    where spbh not in  (select spbh from '+@monthname+') or bmbh not in (select bmbh from '+@monthname+') order by spbh,bmbh'
    exec sp_executesql @strSQL 
    end
    if @ivar='12'
    begin--不要把当前月以前的数据进行更新,中更新到12月份数据,由于上面的操作会返回到当前月以前月的数据
    return --用goto returnlab更好好返回操作的标识状态
    end
    set @i=@i+1 
    end
    */
    declare @i int,@ivar char(2),@strSQL nvarchar(1000)
    set @i=0
    while @i<12
    begin
    set @monthname=left(@monthname,7)
        set @ivar=datename(month,dateadd(month,@i,getdate()))--这样的操作会把返回过去
    if @ivar<='12'
    begin
    set @monthname=rtrim(ltrim(+@monthname))+@ivar
    if @add_op='1'
    begin
    set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select '+@bh+','+@mch+',bmbh,bmmch,'+@leixing+' from bm'
    end
    if @add_op='2'
    begin
    set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select '+@bh+','+@mch+',bmbh,bmmch,'+@leixing+' from sp'
    end
    exec sp_executesql @strSQL 
    end
    if @ivar='12'
    begin--不要把当前月以前的数据进行更新,中更新到12月份数据,由于上面的操作会返回到当前月以前月的数据
    return 1--用goto returnlab更好好返回操作的标识状态
    end
    set @i=@i+1 
    end
    return --返回消息提示更新商品资料或部门资料数据操作成功end
    --出入参数:入操作标识(增加商品还是增加品种),编号,名称。出参数添加商品,部门失败,操作成功运行之后报错误
    消息 245,级别 16,状态 1,过程 adddata,第 84 行
    在将 nvarchar 值 'insert into [dataout03](spbh,spmch,bmbh,bmmch,leixing) select ' 转换成数据类型 int 时失败。
      

  2.   


    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    goALTER procedure [dbo].[createbase] @is_ct nchar(2) as
    begin
    ---定义相关变量
    ---是否重新创建表,如果重新创建表会报现有的表与数据全部清空
    if @is_ct='是'
    begin--1创建表
    --a.基础数据表sp 
    if not exists(SELECT * FROM syb..SysObjects Where XType='U' and name='sp')
    begin
    create table sp(spid int not null primary key,spbh int not null ,spmch nchar(255),status nchar(4) default '可售'
        ,leixing int,[datetime0] datetime default getdate(),[datetime1] datetime default getdate())--0为启售日期,1 停售日期,当两个相同是从开始就启用了
    end
    else 
    begin
    --弹出消息告知已存在是否继续执行
    drop table sp
    create table sp(spid int not null primary key,spbh int not null ,spmch nchar(255),status nchar(4) default '可售'
        ,leixing int,[datetime0] datetime default getdate(),[datetime1] datetime default getdate())--0为启售日期,1 停售日期,当两个相同是从开始就启用了
    end
    exec sp_configure 'show advanced options',1  --配置操作不然会导入数据不成功
    reconfigure 
    exec sp_configure 'Ad Hoc Distributed Queries',1 
    reconfigure
    truncate table sp
    insert into sp(spid,spbh,spmch,leixing) SELECT spid,spbh,spmch,leixing FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
    'Data Source=K:\sybtg\基础资料\商品编号.xls;User ID=Admin;Password=;Extended properties="Excel 8.0;HDR=Yes;";Persist Security Info=False')...[sp$]
    --b.基础数据表bm
    if not exists(select * from syb..sysobjects where xtype='U' and name='bm')
    begin  
    create table bm(bmid int not null primary key,bmbh int not null ,bmmch nchar(255),status nchar(4) default '可用'
        ,[datetime0] datetime default getdate(),[datetime1] datetime default getdate())--0为启用日期,1 停用日期,当两个相同是从开始就启用了,或者新增的
    end
    else
    begin
    --弹出消息告知已存在是否继续执行
    drop table bm
    create table bm(bmid int not null primary key,bmbh int not null ,bmmch nchar(255),status nchar(4) default '可用'
        ,[datetime0] datetime default getdate(),[datetime1] datetime default getdate())--0为启用日期,1 停用日期,当两个相同是从开始就启用了,或者新增的
    end
    --同时在这导入部门基础数据
    ------------------------------------------------------------------------------------
    --在这同上面一样用函数来调用就行了
    ------------------------------------------------------------------------------------
    truncate table bm
    insert into bm(bmid,bmbh,bmmch) SELECT bmid,bmbh,bmmch FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
    'Data Source=K:\sybtg\基础资料\分店资料.xls;User ID=Admin;Password=;Extended properties="Excel 8.0;HDR=Yes;";Persist Security Info=False')...[bm$]
    ---对月份表的创建
    declare @monthname nchar(9) ,@strSQL nvarchar(1000)
    declare @i int,@ivar char(2)
    set @monthname='dataout01'
    set @i=0
    while @i<12
    begin
    set @monthname=left(@monthname,7)
        set @ivar=datename ( month, dateadd(month, @i, getdate()) )
    set @monthname=rtrim(ltrim(@monthname))+@ivar
    if not exists(select * from syb..sysobjects where xtype='u' and name=@monthname)
    begin
    select @strSQL=dbo.getstrdataout(@monthname)--调用建表函数字串
    EXEC sp_ExecuteSql @strSQL
    set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing)select a.spbh,a.spmch,b.bmbh,b.bmmch,a.leixing from sp a,bm b'
    EXEC sp_ExecuteSql @strSQL
    end
    else
    begin
    set @strSQL='drop table ['+@monthname+']'
    EXEC sp_ExecuteSql @strSQL
    select @strSQL=dbo.getstrdataout(@monthname)--调用建表函数字串
    EXEC sp_ExecuteSql @strSQL
    set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing)select a.spbh,a.spmch,b.bmbh,b.bmmch,a.leixing from sp a,bm b'
    EXEC sp_ExecuteSql @strSQL
    end
       set @i = @i + 1
    end
    return  0 --0值表示成功
    end
    else
    return  1--是返回的整型值,(非整返回不了)除非特别指明,所有系统存储过程返回,0值表示成功,返回非零值则表示失败。end
    这个是我创建基础数据的过程
    我快无力了,要是这个也能看到内存数据从中调就好了,高人快来啊
      

  3.   

    函数要求有确定性,即同样的输入,输出永远是一样的
    所以有很多限制,包括不能执行动态sql
      

  4.   

    不使用动态sql好了
    看代码,好像就是12个insert嘛
      

  5.   

    不知道sql2008是否开始支持以变量作为select/insert/delete的表名
      

  6.   

    没有明白上楼的意思,但你看一下我的代码,就会明白,变量作为select/insert/delete的表名
      

  7.   

    你是用动态sql实现表名的动态
    我说的是直接:update @tablename set ... 好像记得哪里提起过sql2008支持这样的sql了
      

  8.   

    表变量,sql2000就有了
    字符串变量做表名,sql2005都还不支持
      

  9.   

    字符串变量做表名,与表变量,这样一起用的话不会冲突吗?
    这个现在不是大问题,麻烦你帮我看一下另外一个贴子吧
    http://topic.csdn.net/u/20110423/19/da4f4444-1366-4063-bff1-5863f2681d05.html?seed=1751715844&r=72947271#r_72947271
      

  10.   

               set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select '+@bh+','+@mch+',bmbh,bmmch,'+@leixing+' from bm'
     
    改成           set @strSQL='insert into ['+@monthname+'](spbh,spmch,bmbh,bmmch,leixing) select '+cast(@bh as nvarchar(100))+','+cast(@mch as nvarchar(100))+',bmbh,bmmch,'+cast(@leixing as nvarchar(100))+' from bm'
    其他地方修改类似