如何在存储过程中循环插入记录?

angel_zxq 2009-07-12 10:07:38
我想实现一个投票的功能,写了一个存储过程,用来记录下投票的内容。先说一下我的表:
vote--投票表:
id int identity(1,1) primary key not null,--投票编号
uid int null,--用户编号(跟用户表的用户id联系)
topic varchar(100) not null,--投票主题
content text null,--投票详细说明
date datetime default(getdate())not null,--投票发起日期
todate datetime null,--投票截止日期
vconfine varchar(30) null,--投票限制
lconfine varchar(30) null--点评限制
cont int null--投票人数
voteDetail--投票详情表:
id int identity(1,1) primary key not null,--编号
vid int null,--投票编号(跟投票表中的id联系)
cand varchar(500) null,--投票选项
[option] varchar(30) null--投票形式
存储过程:
create proc releaseVote--发布投票
(
@uid int,
@topic varchar(100),
@content text,
@cand varchar(500),
@option varchar(30)
)
as
declare @vid int ,/*投票编号*/ @len int,@i int ,/*循环变量*/ @str varchar(100) ,/*用来分割的变量*/ @id varchar(30)--测试数据
begin tran
insert into vote(uid,topic,content) values(@uid,@topic,@content)
select @vid = max(id) from vote
--这里准备根据页面中有多少文本框而循环插入??
set @str=@can
while charindex(',',@str)>0
begin
select @vid = max(id) from vote
set @str = left(@str,charindex(',',@str)-1)
insert into voteDetail(vid,cand,[option]) values(@vid,@str,@option)
set @str = stuff(@str,1,charindex(',',@str),'')
end
if(@@error > 0)
rollback
commit

exec releaseVote '','aaaaaa','','王老吉,水溶C100,果粒橙,','多选'

实现的结果:
投票表:
id topic content
-----------------------------
1 aaaaaa
投票详情表:
id vid cand option
-----------------------------------
1 1 王老吉 多选

我希望实现的结果:
投票表:
id topic content
-----------------------------
1 aaaaaa
投票详情表:
id vid cand option
-----------------------------------
1 1 王老吉 多选
2 1 水溶C100 多选
3 1 果粒橙 多选

想实现该结果存储过程应该怎么改?现在的问题就是执行该存储过程好像不能循环了,只能插入一条记录了,是不是循环部分有问题?该怎么改?哪位高手能指点下,谢谢!!
...全文
344 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
create table vote
(
id int identity(1,1) primary key not null,--投票编号
[uid] int null,--用户编号(跟用户表的用户id联系)
topic varchar(100) not null,--投票主题
content text null,--投票详细说明
[date] datetime default(getdate())not null,--投票发起日期
todate datetime null,--投票截止日期
vconfine varchar(30) null,--投票限制
lconfine varchar(30) null,--点评限制
cont int --投票人数
)
go
create table voteDetail--投票详情表:
(
id int identity(1,1) primary key not null,--编号
vid int null,--投票编号(跟投票表中的id联系)
cand varchar(500) null,--投票选项
[option] varchar(30) null--投票形式
)

go
--建个拆分字符串的函数
CREATE FUNCTION f_splitSTR(
@s varchar(8000), --待分拆的字符串
@split varchar(10) --数据分隔符
)RETURNS @re TABLE(col varchar(100))
AS
BEGIN
DECLARE @splitlen int
SET @splitlen=LEN(@split+'a')-2
WHILE CHARINDEX(@split,@s)>0
BEGIN
INSERT @re VALUES(LEFT(@s,CHARINDEX(@split,@s)-1))
SET @s=STUFF(@s,1,CHARINDEX(@split,@s)+@splitlen,'')
END
INSERT @re VALUES(@s)
RETURN
END
GO
alter proc releaseVote--发布投票
(
@uid int,
@topic varchar(100),
@content text,
@cand varchar(500),
@option varchar(30)
)
as
begin
declare @vid int ,/*投票编号*/ @str varchar(100) ,/*用来分割的变量*/ @id varchar(30)--测试数据

insert into vote(uid,topic,content) values(@uid,@topic,@content)
select @vid = max(id) from vote
insert into voteDetail(vid,cand,[option])
select @vid,*,@option
from dbo.f_splitSTR(@cand,',')--调用函数
end
go
exec releaseVote '','aaaaaa','','王老吉,水溶C100,果粒橙','多选'

select id,topic,content from vote
select id ,vid ,cand from voteDetail
/*
id topic content
----------- -----------------------------------------------------------
1 aaaaaa

(1 行受影响)

id vid cand
----------- ----------- -----------------------
1 1 王老吉
2 1 水溶C100
3 1 果粒橙

(3 行受影响)*/
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 angel_zxq 的回复:]
我之前用的存储过程,后来用了函数就行了,为什么存储过程不行而函数就行呢,问题解决了,谢谢!!
[/Quote]
你看楼上我写的 应该也可以的。。
把其他贴也结了
angel_zxq 2009-07-13
  • 打赏
  • 举报
回复
我之前用的存储过程,后来用了函数就行了,为什么存储过程不行而函数就行呢,问题解决了,谢谢!!
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
drop table vote,voteDetail
go

create table vote
(
id int identity(1,1) primary key not null,--投票编号
[uid] int null,--用户编号(跟用户表的用户id联系)
topic varchar(100) not null,--投票主题
content text null,--投票详细说明
[date] datetime default(getdate())not null,--投票发起日期
todate datetime null,--投票截止日期
vconfine varchar(30) null,--投票限制
lconfine varchar(30) null,--点评限制
cont int --投票人数
)
go
create table voteDetail--投票详情表:
(
id int identity(1,1) primary key not null,--编号
vid int null,--投票编号(跟投票表中的id联系)
cand varchar(500) null,--投票选项
[option] varchar(30) null--投票形式
)

go
alter proc releaseVote--发布投票
(
@uid int,
@topic varchar(100),
@content text,
@cand varchar(500),
@option varchar(30)
)
as
declare @vid int , @str varchar(100) ,@s varchar(100)
begin tran
insert into vote(uid,topic,content) values(@uid,@topic,@content)
select @vid = max(id) from vote
set @str=@cand
while charindex(',',@str)>0
begin
set @s=(LEFT(@str,CHARINDEX(',',@str)-1))
insert into voteDetail(vid,cand,[option])
values(@vid,@s,@option)
SET @str=STUFF(@str,1,CHARINDEX(',',@str),'')
end
insert into voteDetail(vid,cand,[option])--
values(@vid,@str,@option)--这里修改了下 可以了 去试试

if(@@error > 0)
rollback
else
commit

go
exec releaseVote '','aaaaaa','','王老吉,水溶C100,果粒橙','多选'
go
select id ,topic, content from vote
select * from voteDetail
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
我这可以啊。。
你用函数的方法也是这样啊?
angel_zxq 2009-07-13
  • 打赏
  • 举报
回复
谢谢feixianxxx,可是为什么最后会多循环一次?
alter proc releaseVote--发布投票
(
@uid int,
@topic varchar(100),
@content text,
@cand varchar(500),
@option varchar(30)
)
as
declare @vid int , @str varchar(100) ,@s varchar(100)
begin tran
insert into vote(uid,topic,content) values(@uid,@topic,@content)
select @vid = max(id) from vote
set @str=@cand
while charindex(',',@str)>0
begin
set @s=(LEFT(@str,CHARINDEX(',',@str)-1))
insert into voteDetail(vid,cand,[option])
values(@vid,@s,@option)
SET @str=STUFF(@str,1,CHARINDEX(',',@str),'')
end
insert into voteDetail(vid,cand,[option])
values(@vid,@s,@option)
if(@@error > 0)
rollback
else
commit


exec releaseVote '','aaaaaa','','王老吉,水溶C100,果粒橙','多选'

/*
id topic content
-------------------------------
1 aaaaaa

(1 行受影响)

id vid cand option
------------------------------------
1 1 王老吉 多选
2 1 水溶C100 多选
3 1 果粒橙 多选
4 1 果粒橙 多选

(4 行受影响)
*/


为什么会有四行?难道是多循环了一次?能否再帮忙看看,问题解决了我会结贴的,谢谢!!
angel_zxq 2009-07-13
  • 打赏
  • 举报
回复
再问个问题:我在程序中放了17个文本框,用来放投票时的选项,执行上诉存储过程代码如下:

using (SqlConnection conn = new SqlConnection(str))
{
conn.Open();
SqlCommand comm = new SqlCommand("releaseVote", conn);
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add("@uid", SqlDbType.Int);
comm.Parameters["@uid"].Value = DBNull.Value;
comm.Parameters.Add("@topic", SqlDbType.VarChar);
comm.Parameters["@topic"].Value = txtTopic.Text;
comm.Parameters.Add("@content", SqlDbType.VarChar);
comm.Parameters["@content"].Value = txtContent.Text;
comm.Parameters.Add("@cand", SqlDbType.VarChar);
comm.Parameters["@cand"].Value = txtCand1.Text + "," + txtCand2.Text + "," + txtCand3.Text + "," + txtCand4.Text + "," + txtCand5.Text + "," + txtCand6.Text + "," + txtCand7.Text + "," + txtCand8.Text + "," + txtCand9.Text + "," + txtCand10.Text + "," + txtCand11.Text + "," + txtCand12.Text + "," + txtCand13.Text + "," + txtCand14.Text + "," + txtCand15.Text + "," + txtCand16.Text + "," + txtCand17.Text;
comm.Parameters.Add("@option", SqlDbType.VarChar);
comm.Parameters["@option"].Value = dropOption.SelectedValue;
comm.ExecuteNonQuery();

现在的问题是用户用可能不会输入那么多选项,有可能只输入5,6个,那剩下的几个空白框中的内容也会往表里插空白记录,如果不想要这些空白记录怎么办??
比如:我插了3个测试数据,结果表中结构是这样:
id vid cand option
-------------------------------------
1 1 王老吉 多选
2 1 水溶C100 多选
3 1 果粒橙 多选
4 1 多选
5 1 多选
6 1 多选
7 1 多选
8 1 多选
9 1 多选
10 1 多选
11 1 多选
12 1 多选
13 1 多选
14 1 多选
15 1 多选
16 1 多选
17 1 多选

那我那剩下的14条多余记录不要怎么办??是不是代码写错了??
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
这个是按照你的思路 不用函数也可以写出来的
drop table vote,voteDetail
go
create table vote
(
id int identity(1,1) primary key not null,--投票编号
[uid] int null,--用户编号(跟用户表的用户id联系)
topic varchar(100) not null,--投票主题
content text null,--投票详细说明
[date] datetime default(getdate())not null,--投票发起日期
todate datetime null,--投票截止日期
vconfine varchar(30) null,--投票限制
lconfine varchar(30) null,--点评限制
cont int --投票人数
)
go
create table voteDetail--投票详情表:
(
id int identity(1,1) primary key not null,--编号
vid int null,--投票编号(跟投票表中的id联系)
cand varchar(500) null,--投票选项
[option] varchar(30) null--投票形式
)

go
alter proc releaseVote--发布投票
(
@uid int,
@topic varchar(100),
@content text,
@cand varchar(500),
@option varchar(30)
)
as
declare @vid int , @str varchar(100) ,@s varchar(100)
begin tran
insert into vote(uid,topic,content) values(@uid,@topic,@content)
select @vid = max(id) from vote
set @str=@cand
while charindex(',',@str)>0
begin
set @s=(LEFT(@str,CHARINDEX(',',@str)-1))
insert into voteDetail(vid,cand,[option])
values(@vid,@s,@option)
SET @str=STUFF(@str,1,CHARINDEX(',',@str),'')
end
insert into voteDetail(vid,cand,[option])
values(@vid,@s,@option)
if(@@error > 0)
rollback
else
commit

go
exec releaseVote '','aaaaaa','','王老吉,水溶C100,果粒橙','多选'
go
select id ,topic, content from vote
select * from voteDetail
angel_zxq 2009-07-12
  • 打赏
  • 举报
回复
set @str=@can
while charindex(',',@str)>0
->改为
while @@rowcount>0

改后执行就一直停在那里,好像有错?还有我是按照逗号进行分割的,是不是还有其他办法呢?
ChinaJiaBing 2009-07-12
  • 打赏
  • 举报
回复

set @str=@can
while charindex(',',@str)>0
->改为
while @@rowcount>0

22,207

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧