首页 新闻 会员 周边 捐助

怎么能传一条sql 到存储过程中?

0
悬赏园豆:200 [已解决问题] 解决于 2008-08-15 18:37
怎么能传一条sql 到存储过程中?
问题补充: 我自己解决了,但是还有问题, /* * 执行一个sql的存储过程 */ if exists(select *from sysobjects where name='proc_dingdang') drop procedure proc_dingdang go create procedure proc_dingdang --执行sql语句 @sqlone varchar(1000) as ---- 创建一个临时表 1 declare @tb table(byer ntext not null,fare money not null) -------创建一个临时表 2 declare @tbo table(a int) ---总钱数 declare @totalMoney money, ---人数 @number int ---1 把数据放入 @tbdingdang 表中 exec (N'insert '+@tb+''+@sqlone) ---2 对@t 表进行操作 insert @tbo select dbo.f_split(byer,',') as byerCount from @tb -----3 查询出总价钱,总人数 select @number=sum(a) from @tbo select @totalMoney=sum(fare) from @tb -----4 显示信息 select @number as number,@totalMoney as Totmoney go 我的想法是传一条查询的sql语句到存储过程中, 并且把查询出来的数据放入临时表中, 我直接创建一个tabel 就可以,但是我建一个临时表,就不可以!总报错这个错: 必须声明标量变量 "@tb"。 问题我虽然已经解决,但是为什么创建一个临时表就不行???很困惑??
文杰的主页 文杰 | 初学一级 | 园豆:180
提问于:2008-07-31 15:45
< >
分享
最佳答案
0
1. 组装的SQL语句错了:你的语句中将字符串类型跟表类型加到一起了。 2. 表变量的使用方式错误:作用域的问题。 3. 表变量的使用方式不正确:表变量存储方式的问题。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 你的这个SQL语句并没有涉及表变量的其他问题,因此这里就以上几个问题来修正你的代码。 仅修正问题1、2: declare @tb table(byer ntext not null,fare money not null) ------> create table #tb (byer ntext not null,fare money not null) exec (N'insert '+@tb+''+@sqlone) ------> exec (N'insert '+'#tb '+@sqlone) 后面相应的@tb全部改为#tb,即可 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 上面的写法有不少的性能问题,不管是SQL语句本身还是整个方案,包括我上面给出的修改方案。所以,现在考虑修正第3个问题 下面给出一个稍微好一些的写法(注意,方案本身的缺陷只能根据你的实际业务来解决了)整个存储过程可以修改为以下形式: EXEC (N'SELECT SUM(dbo.f_split(byer,'','')) AS number, SUM(fare) AS Totmoney FROM (' + @sqlone + ') AS A') 里面的byer和fare需要你自己再调整,那就看你传入的SQL语句中的字段命名是怎么样的了。 这样修改之后,能够避免一些不必要的性能损失。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 最后补充一点:修改后的方案虽然会比之前的好一些,不过整体方案仍然不是很合理,而且这样的存储过程还会降低应用程序的可维护性。建议在今后的设计中尽量不要使用这样的方案。
电机拖动 | 小虾三级 |园豆:1295 | 2008-08-08 13:38
其他回答(7)
0
当作字符串类型的变量用存储过程传吧……
齐.net | 园豆:1421 (小虾三级) | 2008-07-31 15:51
0
--存储过程 create proc p_test @sql varchar(500) as exec(sql)
Tony Lu | 园豆:232 (菜鸟二级) | 2008-07-31 16:38
0
兄弟.分数这个高,是不是浪费了点呀,其实不难的,就是在存储过程中申明个变量,把这个sqly语句(其实就可以当字符串看)传进去,就ok了. create proc proc_Sql ( @ParaSql --接受sql的变量 ) as 要执行的sql语句 然后执行exec(@ParaSql) 如果是在程序中要传递sql语句到数据库中去, SqlConnection con = new SqlConnection();//()中是连接数据库的连接字符串 SqlCommand cmd = new SqlCommand("proc_Sql", con);//()是存储过程名和,连接数据库的对象 cmd.CommandType = CommandType.StoredProcedure;//设置cmd对象执行的是存储过程 cmd.Parameters.Add("@ParaSql", VarChar);//存储过程中的参数,和参数类型 cmd.Parameters["@ParaSql"].Value = StrSql;//把要传入存储过程的的sql语句放在这个里 SqlDataAdapter sda = new SqlDataAdapter(cmd);//创建数据库适配器 DataSet ds = new DataSet();//读取数据库 sda.Fill(ds);//填充数据集 这样就可以把sq;l语句弄到存储过程中去了.
tertyufer | 园豆:35 (初学一级) | 2008-07-31 16:57
0
你为什么要给存储过程传一个sql呢? 这样做通常性能不好,结构也不好。
玉开 | 园豆:8822 (大侠五级) | 2008-07-31 17:41
0
你这种方式定义的@tb是一个表变量,当使用EXEC(@sql)后,@tb表变量就被自动销毁,无法再被访问了。 如果希望在EXEC(@sql)之后能继续被访问,可以采用创建局部临时表(#)的方式。
致博腾远 | 园豆:1389 (小虾三级) | 2008-07-31 20:38
0
把 exec (N'insert '+@tb+''+@sqlone) 改成 exec (N'insert @tb'+@sqlone)
丁学 | 园豆:18730 (专家六级) | 2008-08-01 16:50
0
可以给你提点建议: 在SQL中,可以用Select into语句。我在做项目中,碰到数据比较大的情况下,特别是在分页的时候,都用这个一个,它的效率比Insert into要高不少。如: set @sql=' select identity(int,1,1) as rowindex, id,name,pwd into #temp from tb_userinfo' set @sql=@sql+' select id,name,pwd from #temp where rowindex between '+@start_index+' and '+@end_index set @sql=@sql+' drop table #temp' exec(@sql) 对于楼主的问题,用楼上大家的方法应该可以解决。在此,只是提出一点其它的意见。
Ritchie(乞戈) | 园豆:230 (菜鸟二级) | 2008-08-14 16:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册