求救,存储过程问题 IN

fishidea 2008-06-11 04:11:51
//---存储过程
CREATE PROCEDURE US_Search
@user_id nvarchar(4000),
@bgdate datetime,
@eddate datetime
AS
select USID,regdata,regdatatime from Userdata where USID in (@user_id) and regdata >= @bgdate and regdata <= @eddate
GO


//---查询分析器
exec US_Search '0001','2008-06-01','2008-06-10'
这句话没什么问题,可以正常运行

但是,因为用的是in,所以第一参数'0001'这里想输入多个值,也就是类似'0001','0002','0003'作为一个参数传入@user_id,应该怎么写?请各位XDJM帮忙,万分感谢.....^_^
...全文
141 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
fishidea 2008-06-13
  • 打赏
  • 举报
回复
今天试过了,不转换也一样慢.....我要晕了.....

再不行就不写存储过程了,直接在窗体里写SQL语句就IN了......

还有没有朋友回答一下哇,小弟感激不尽............
律己修心 2008-06-13
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 fishidea 的回复:]
GDC_ZhaoYZ0304360您好
select * from sysobjects where charindex(','+cast(id as nvarchar)+',',','+@ID+',')>0
是可以,但是为什么我改成我能用的后,查询效率很慢......请指点
[/Quote]


','+cast(id as nvarchar)+','
因为对表中的每一行数据的这个ID字段进行了转换操作 所以速度慢了 这个是直接原因
律己修心 2008-06-12
  • 打赏
  • 举报
回复
关注一下
搞不明白
律己修心 2008-06-12
  • 打赏
  • 举报
回复
请XDJM们帮忙啊
是什么意思?
fishidea 2008-06-12
  • 打赏
  • 举报
回复
十分感谢liangCK大哥给出这么详细,但我用SELECT * FROM tbname WHERE fdname IN('+@idlist+')语法改成
select USID,regdata,regdatatime from Userdata where USID in ('+@user_id+') and regdata >= @bgdate and regdata <= @eddate
并不能查询出任何数据嘛.....请指点~谢谢~


其他几位大哥的:exec US_Search '0001,0002,0003','2008-06-01','2008-06-10' 并不能得到什么查询结果的,这我早已试过了,但也十分感谢你们的热心帮助.

问题还没有解决,请XDJM们帮忙啊,谢谢!^_^
fishidea 2008-06-12
  • 打赏
  • 举报
回复
--查询的值列表
DECLARE @idlist varchar(100)
SET @idlist='1,2,3'

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
GO

二楼的这位大哥给出这个方法,为什么根本就查不到呢?有没有人知道?
fuda_1985 2008-06-12
  • 打赏
  • 举报
回复
得用拼接的。
律己修心 2008-06-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 fishidea 的回复:]
GDC_ZhaoYZ0304360您好
select * from sysobjects where charindex(','+cast(id as nvarchar)+',',','+@ID+',')>0
是可以,但是为什么我改成我能用的后,查询效率很慢......请指点
[/Quote]

不好意思,这个我也不太了解啊

我还没有研究过查询效率

等待高手给出优秀的方法吧

哈哈 关注
fishidea 2008-06-12
  • 打赏
  • 举报
回复
GDC_ZhaoYZ0304360您好
select * from sysobjects where charindex(','+cast(id as nvarchar)+',',','+@ID+',')>0
是可以,但是为什么我改成我能用的后,查询效率很慢......请指点
fishidea 2008-06-12
  • 打赏
  • 举报
回复
兄弟,没来晚啊~问题还没解决......
fishidea 2008-06-12
  • 打赏
  • 举报
回复
XDJM /*兄弟姐妹的第一个拼音字母*/ ^_^
utpcb 2008-06-12
  • 打赏
  • 举报
回复
我来晚了!
律己修心 2008-06-12
  • 打赏
  • 举报
回复
特殊情况还要特殊处理
比如ID有0001和00011这种

用这个

create proc sp_test
@ID nvarchar(400)
as
select * from sysobjects where charindex(','+cast(id as nvarchar)+',',','+@ID+',')>0
go
exec sp_test '1'
go
exec sp_test '11,21'
go
drop proc sp_test



律己修心 2008-06-12
  • 打赏
  • 举报
回复
create proc sp_test
@ID nvarchar(400)
as
select * from master.dbo.sysdatabases where charindex(cast(dbid as nvarchar),@ID)>0
go
exec sp_test '1'
go
exec sp_test '1,2'
go
drop proc sp_test


试试charindex

我测试的通过了


kong521 2008-06-11
  • 打赏
  • 举报
回复
exec US_Search '0001,0002,0003','2008-06-01','2008-06-10'
呵呵
只要第一个参数在单引号内
并且没有单引号
你在再多都没关系
exec US_Search '0001,0002,0003...','2008-06-01','2008-06-10'
laowan688 2008-06-11
  • 打赏
  • 举报
回复
exec US_Search '0001,0002,0003','2008-06-01','2008-06-10'
arrow_gx 2008-06-11
  • 打赏
  • 举报
回复
exec US_Search '0001,0002,0003','2008-06-01','2008-06-10' 
-狙击手- 2008-06-11
  • 打赏
  • 举报
回复
CREATE PROCEDURE US_Search
@user_id nvarchar(4000),
@bgdate datetime,
@eddate datetime
AS
select USID,regdata,regdatatime from Userdata where charindex(','+ltrim(USID)+',',','+@user_id+',') > 0 and regdata >= @bgdate and regdata <= @eddate
GO


---


exec US_Search '0001,0002,0003','2008-06-01','2008-06-10'
liangCK 2008-06-11
  • 打赏
  • 举报
回复
动态sql语句基本语法 
1 :普通SQL语句可以用Exec执行

eg: Select * from tableName
Exec('select * from tableName')
Exec sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

eg:
declare @fname varchar(20)
set @fname = 'FiledName'
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec('select ' + @fname + ' from tableName') -- 请注意 加号前后的 单引号的边上加空格

当然将字符串改成变量的形式也可
declare @fname varchar(20)
set @fname = 'FiledName' --设置字段名

declare @s varchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s) -- 成功
exec sp_executesql @s -- 此句会报错



declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s) -- 成功
exec sp_executesql @s -- 此句正确

3. 输出参数
declare @num int,
@sqls nvarchar(4000)
set @sqls='select count(*) from tableName'
exec(@sqls)
--如何将exec执行结果放入变量中?

declare @num int,
@sqls nvarchar(4000)
set @sqls='select @a=count(*) from tableName '
exec sp_executesql @sqls,N'@a int output',@num output
select @num
liangCK 2008-06-11
  • 打赏
  • 举报
回复
--1. 构造使用IN子句的动态Transact-SQL方法进行编号查询

--a. 要查询的字段类型是数字型

--查询的值列表
DECLARE @idlist varchar(100)
SET @idlist='1,2,3'

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
GO

--b. 要查询的字段类型是字符型
--查询的值列表已经加上了字符串边界符
DECLARE @idlist varchar(100)
SET @idlist='''a'',''b''''a'',''c'''

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
GO

--查询的值列表没有字符串边界符
DECLARE @idlist varchar(100)
SET @idlist='a,b''a,c'

--由于是字段类型是,所以在拼接时,必须为其加上字符串边界符(')
DECLARE @s varchar(1000)
SET @s=''''
+REPLACE(REPLACE(@idlist,'''',''''''),',',''',''')
+''''

--拼接并执行动态Transact-SQL语句
EXEC('SELECT * FROM tbname WHERE fdname IN('+@s+')')
GO

/*=====================================================*/


--2. 使用LIKE或者PATINDEX进行编号查询
--查询的值列表
DECLARE @idlist varchar(100)
SET @idlist='1,2,3'

--查询
SELECT * FROM tbname WHERE CHARINDEX(','+RTRIM(fdname)+',',','+@idlist+',')>0
SELECT * FROM tbname WHERE PATINDEX('%,'+RTRIM(fdname)+',%',','+@idlist+',')>0
SELECT * FROM tbname WHERE ','+@idlist+',' LIKE '%,'+RTRIM(fdname)+',%'
GO

/*=====================================================*/


--3. 编号查询中常见的错误
--a. 最容易犯的错误:表达式充当表达式列表。
DECLARE @s varchar(100)
SET @s='1'
SELECT id,name FROM sysobjects WHERE id IN(@s)
/*--结果
id name
---------------- ------------
1 sysobjects
--*/

SET @s='1,2,3'
SELECT id,name FROM sysobjects WHERE id IN(@s)
/*--结果
服务器: 消息 245,级别 16,状态 1,行 3
将 varchar 值 '1,2,3' 转换为数据类型为 int 的列时发生语法错误。
--*/
GO

--b. 生成动态Transact-SQL语句时忽略了数据类型。
DECLARE @s varchar(100)
SET @s='U,S'
EXEC('SELECT id,name FROM sysobjects WHERE id IN('+@s+')')
/*--结果:
服务器: 消息 207,级别 16,状态 3,行 1
列名 'S' 无效。
服务器: 消息 207,级别 16,状态 1,行 1
列名 'U' 无效。
--*/
GO

--c. 忽略了比较的精确性问题。
--要查询的数据
DECLARE @t TABLE(col varchar(10))
INSERT @t SELECT '1'
UNION ALL SELECT '11'
UNION ALL SELECT '111'
UNION ALL SELECT '22'

--查询
DECLARE @s varchar(100)
SET @s='111,22'
SELECT * FROM @t WHERE CHARINDEX(col,@s)>0
/*--结果
col
----------
1
11
111
22
-*/
GO

34,873

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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