■■ 这个“不存在”的存储过程如何写?

五维思考 2008-12-24 10:27:29

1、字符串:M1234,M2345,M7986,M3456(编号个数不确定,可能多,可能少)
2、TB表NUM字段:
-----------

M1234
M1235
M3454
M3456
....

3、要求执行存储过程:Query_inexistence 'M1234,M2345,M7986,M3456'得到结果集
-----
M2345
M7986

解释:也就是说,看给定的字符串中所含编号哪些不在TB表中,因为TB表中数据量很大,所以这个存储过程要求执行效率较高才行。请高手帮忙!
...全文
157 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
五维思考 2008-12-24
  • 打赏
  • 举报
回复
本人最终采用了 5 楼 csdyyr 的方法

爱新觉罗.毓华 的方法也不错,感谢热心帮助

近身剪 的方法得不到正确的结果,但改一下就行了,在此表示感谢
claro 2008-12-24
  • 打赏
  • 举报
回复
帮顶啦
等不到来世 2008-12-24
  • 打赏
  • 举报
回复
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([NUM] varchar(5))
insert [tb]
select 'M1234' union all
select 'M1235' union all
select 'M3454' union all
select 'M3456'
go
--select * from [tb]

if object_id('p','p') is not null
drop proc p
go
create proc p
@s nvarchar(1000)
as
select top 100 id=identity(int,1,1) into # from syscolumns,sysobjects

select num=substring(@s,id,charindex(',',@s+',',id)-id)
into #1
from #
where charindex(',',','+@s,id)=id

delete #1
from tb
where #1.num=tb.NUM

select num from #1
go

exec p 'M1234,M2345,M7986,M3456'
/*
num
-------
M2345
M7986
*/
水族杰纶 2008-12-24
  • 打赏
  • 举报
回复
CREATE PROC PROC_TEST
@STR VARCHAR(1000)
AS
SELECT * FROM TB WHERE PATINDEX(','+NUM+',',','+@STR+',')>0
五维思考 2008-12-24
  • 打赏
  • 举报
回复
哇,这么多答案,先谢谢各位兄弟,我现在试试看
viva369 2008-12-24
  • 打赏
  • 举报
回复
楼主试下哪个比较快,试之前清下缓存
dbcc dropcleanbuffers
viva369 2008-12-24
  • 打赏
  • 举报
回复
试试这个

create procedure Query_inexistence
(
@str nvarchar(max)
)
as
begin

declare @sql varchar(max)
set @sql =
'
select *
from
(
select null NUM union all select ' + replace(@str,',',' union all select ')
+')tbl
where not exists(select 1 from TB where tb.num = tbl.num) and tbl.num is not null
'
exec (@sql)
end
jinjazz 2008-12-24
  • 打赏
  • 举报
回复
--建立测试环境
set nocount on
create table test(num varchar(20))
insert into test select 'M1234'
insert into test select 'M1235'
insert into test select 'M3454'
insert into test select 'M3456'
go
--测试
select * from test where charindex(','+num+',',
',M1234,M2345,M7986,M3456,')>0

--删除测试环境
drop table test
set nocount off

/*
num
--------------------
M1234
M3456
*/
jinjazz 2008-12-24
  • 打赏
  • 举报
回复
select * from test where charindex(','+num+',',
',M1234,M2345,M7986,M3456,')>0
csdyyr 2008-12-24
  • 打赏
  • 举报
回复
CREATE TABLE TB(NUM VARCHAR(5))
INSERT TB
SELECT 'M1234' UNION ALL
SELECT 'M1235' UNION ALL
SELECT 'M3454' UNION ALL
SELECT 'M3456'


DECLARE @SQL VARCHAR(8000)
SET @SQL='SELECT COL='''+REPLACE('M1234,M2345,M7986,M3456', ',', ''' UNION ALL SELECT ''')+''''

SET @SQL='SELECT COL FROM ('+@SQL+') T LEFT JOIN TB ON COL=NUM WHERE NUM IS NULL'

EXEC(@SQL)

DROP TABLE TB
/*
COL
-----
M2345
M7986
*/
dawugui 2008-12-24
  • 打赏
  • 举报
回复
create table TB(NUM varchar(10))
insert into tb values('M1234')
insert into tb values('M1235')
insert into tb values('M3454')
insert into tb values('M3456')
go
/*
名称:fn_split函数.
功能:实现字符串分隔功能的函数
*/
create function dbo.fn_split(@inputstr varchar(8000), @seprator varchar(10))
returns @temp table (a varchar(200))
as
begin
declare @i int
set @inputstr = rtrim(ltrim(@inputstr))
set @i = charindex(@seprator , @inputstr)
while @i >= 1
begin
insert @temp values(left(@inputstr , @i - 1))
set @inputstr = substring(@inputstr , @i + 1 , len(@inputstr) - @i)
set @i = charindex(@seprator , @inputstr)
end
if @inputstr <> '\'
insert @temp values(@inputstr)
return
end
go

--调用
declare @s varchar(100)
set @s = 'M1234,M2345,M7986,M3456'

select m.* from (select * from dbo.fn_split(@s,',')) m where a not in (select * from tb)

drop table tb
drop function dbo.fn_split

/*
a
------
M2345
M7986

(所影响的行数为 2 行)
*/


liangCK 2008-12-24
  • 打赏
  • 举报
回复

'M1234,M2345,M7986,M3456'

变为
M1234
M2345
M7986
...
...

的形式.然后再JOIN
dawugui 2008-12-24
  • 打赏
  • 举报
回复

/*
标题:分解字符串并查询相关数据
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-03-18
地点:广东深圳
说明:通过使用函数等方法分解字符串查询相关数据。

问题:通过分解一个带某种符号分隔的字符串在数据库中查找相关数据。
例如 @str = '1,2,3',查询下表得到记录1,4,5,6
ID TypeID
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
6 6,7
*/
-----------------------------
create table tb (ID int , TypeID varchar(30))
insert into tb values(1 , '1,2,3,4,5,6,7,8,9,10,11,12')
insert into tb values(2 , '2,3')
insert into tb values(3 , '3,7,8,9')
insert into tb values(4 , '2,6')
insert into tb values(5 , '4,5')
insert into tb values(6 , '6,7')
go
-----------------------------
--如果仅仅是一个,如@str = '1'.
declare @str as varchar(30)
set @str = '1'
select * from tb where charindex(',' + @str + ',' , ',' + TypeID + ',') > 0
select * from tb where ',' + TypeID + ',' like '%,' + @str + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
(所影响的行数为 1 行)
*/

-----------------------------
--如果包含两个,如@str = '1,2'.
declare @str as varchar(30)
set @str = '1,2'
select * from tb where charindex(',' + left(@str , charindex(',' , @str) - 1) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',' , ',' + typeid + ',') > 0
select * from tb where ',' + typeid + ',' like '%,' + left(@str , charindex(',' , @str) - 1) + ',%' or
',' + typeid + ',' like '%,' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
4 2,6
(所影响的行数为 3 行)
*/

-------------------------------------------
--如果包含三个或四个,用PARSENAME函数来处理.
declare @str as varchar(30)
set @str = '1,2,3,4'
select * from tb where
charindex(',' + parsename(replace(@str , ',' , '.') , 4) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 3) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 2) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 1) + ',' , ',' + typeid + ',') > 0
select * from tb where
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 4) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 3) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 2) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 1) + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/

---------------------------------------
--如果超过四个,则只能使用函数或动态SQL来分解并查询数据。
/*
名称:fn_split函数.
功能:实现字符串分隔功能的函数
*/
create function dbo.fn_split(@inputstr varchar(8000), @seprator varchar(10))
returns @temp table (a varchar(200))
as
begin
declare @i int
set @inputstr = rtrim(ltrim(@inputstr))
set @i = charindex(@seprator , @inputstr)
while @i >= 1
begin
insert @temp values(left(@inputstr , @i - 1))
set @inputstr = substring(@inputstr , @i + 1 , len(@inputstr) - @i)
set @i = charindex(@seprator , @inputstr)
end
if @inputstr <> '\'
insert @temp values(@inputstr)
return
end
go

--调用
declare @str as varchar(30)
set @str = '1,2,3,4,5'

select distinct m.* from tb m,
(select * from dbo.fn_split(@str,',')) n
where charindex(',' + n.a + ',' , ',' + m.typeid + ',') > 0

drop table tb
drop function dbo.fn_split

/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/

------------------------------------------
--使用动态SQL的语句。
declare @str varchar(200)
declare @sql as varchar(1000)
set @str = '1,2,3,4,5'
set @sql = 'select ''' + replace(@str , ',' , ''' as id union all select ''')
set @sql = @sql + ''''
set @sql = 'select distinct a.* from tb a , (' + @sql + ') b where charindex(' + ''','' + b.id + ' + ''',''' + ' , ' + ''','' + a.typeid + ' + ''',''' + ') > 0 '
exec (@sql)
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/

dawugui 2008-12-24
  • 打赏
  • 举报
回复
先分解字符串,然后再比较.
Venus 世界上第一款3D浏览器 2010年11月17日发行 【内含PDF操作指南】 如果安装时弹出“runtime error”,请重试安装! 网页界面将以3D全景窗口方式展现?17日的深圳高交会上,以色列VisualDomain软件公司开发的3D浏览Venus全球首发。 记者在发布展示会上了解到,在该款浏览器界面上可以同时呈现多个网络页面。通过移动鼠标,横竖排列整齐的多个页面以滚动方式展现,各页面还可任意放大、缩小,想查看哪个页面时点击放大即可。 “因为多个页面同时呈现,这种直观的浏览方式大大提高了用户浏览的效率。”VisualDomain公司总裁YoavShefi介绍,这是目前世界上最快的一种浏览器浏览方式。不仅如此,通过“3D映射”的功能,该浏览器还可选中页面上的某一张图片,去除背景,使图片竖起来,取得栩栩如生的3D效果。 中文名: 全球首款3D浏览器 英文名: Venus 别名: 维纳斯网页浏览新体验 资源格式: 安装包 版本: 0.2.7.81 简体中文版 发行时间: 2010年11月17日 制作发行: Visual Domains Ltd.地区: 大陆,以色列 语言: 简体中文 简介: 软件类型:主页浏览/浏览辅助 软件性质:简体中文安装版 处理操作系统:windows 应用平台:Vista/2003/XP/Win2000/NT/7 网站链接:http://www.visualdomains-china.com/index.php 【软件介绍】 维纳斯,完全自由的网络体验。维纳斯为你打造一片特别的网络浏览环境,让你在一个开阔的界面同时浏览所有网页。用维纳斯进行网络搜索,所有结果尽在眼前。 想象一下这样一种上网模式:你想找的网页和图片全部一起展示在你面前。众多网站形成一个world,而你可以鸟瞰这个world;你随时可以放大感兴趣的网页进行查看。 这就是Venus的world。 常见问题 1.Venus需要什么特殊的硬件或软件吗? Venus?支持所有主流电脑操作系统(Windows XP, Vista, or windows 7),在3年内的电脑上可以很流畅地运行。建议配置双核处理器1.66 GHz及以上,显存128MB以上(推荐为256MB),内存1.5GB以上。 2.我要怎样联系Venus ?的团队? 作为对用户体验和用户反馈抱有坚定信仰的Visual Domains,一直在和全球的Venus ?用户保持沟通。如果你有任何疑问或希望了解我们,请发送邮件至support@visualdomains.com或通过我们网站的“联系我们”和我们联系。你还可以通过facebook和twitter和我们联系。 3.下载Venus ?和下载Venus ?插件有什么区别? Venus ?可以作为一个插件安装在你的浏览器上面,同时也可作为一个独立的浏览器存在。我们的Venus ?插件可以让你直接在你的浏览器上面使用Venus ?。目前开放的插件是“venus 搜索”,你可以将该插件安装在你的IE或火狐浏览器工具栏上,如果你在Venus搜索工具栏里面进行搜索,你看到的结果就是以Venus的特殊形式展示的。目前我们正在开发更多的插件。 4.Visual Domains的隐私政策是什么? Visual Domains严格执行隐私保护相关国际标准,详情请在“法律声明”里面的隐私政策部分查看。 5.目前还有没有在开发什么项目吗? 我们的团队一直在寻找提升用户体验的方法。目前我们正在研发几个项目例如java applets和quick time兼容性。 6.我安装Venus?的时候看到一条提示:你的电脑显卡不能完全支持Venus?的要求...... 您看到这条提示信息可能是因为两种情况:一,您的显卡不能完全支持Venus的性能要求;二,您的显卡驱动是旧版本。Venus无法识别到底是哪一种问题,建议您请专业人士鉴别是否更新显卡还是驱动。 2010.11.23 补充: 在使用过程中发现,浏览器貌似只会存储历史记录,如怕占用资源可以自行清理。 历史记录在: 我的文档\Venus\Internal\AutoSave
P2P文件共享 前面有人文嗅探器的问题,我在这里做个详细的解释: 嗅探器(snifffer)就是能够捕获网络报文的设备。嗅探器的正当用处在于分析网络的流量,以便找出所关心的网络中潜在的问题。例如,假设网络的某一段运行得不是很好,报文的发送比较慢,而我们又不知道问题出在什么地方,此时就可以用嗅探器来作出精确的问题判断。 嗅探器在功能和设计方面有很多不同。有些只能分析一种协议,而另一些可能能够分析几百种协议。一般情况下,大多数的嗅探器至少能够分析下面的协议: 标准以太网 TCP/IP IPX DECNet 嗅探器通常是软硬件的结合。专用的嗅探器价格非常昂贵。另一方面,免费的嗅探器虽然不需要花什么钱,但得不到什么支持。 嗅探器与一般的键盘捕获程序不同。键盘捕获程序捕获在终端上输入的键值,而嗅探器则捕获真实的网络报文。嗅探器通过将其置身于网络接口来达到这个目的——例如将以太网卡设置成杂收模式。(为了理解杂收模式是怎么回事,先解释局域网是怎么工作的)。 数据在网络上是以很小的称为帧(Ftame)的单位传输的帧由好几部分组成,不同的部分执行不同的功能。(例如,以太网的前12个字节存放的是源和目的的地址,这些位告诉网络:数据的来源和去处。以太网帧的其他部分存放实际的用户数据、TCP/IP的报文头或IPX报文头等等)。 帧通过特定的称为网络驱动程序的软件进行成型,然后通过网卡发送到网线上。通过网线到达它们的目的机器,在目的机器的一端执行相反的过程。接收端机器的以太网卡捕获到这些帧,并告诉操作系统帧的到达,然后对其进行存储。就是在这个传输和接收的过程中,嗅探器会造成安全方面的问题。 每一个在LAN上的工作站都有其硬件地址。这些地址唯一地表示着网络上的机器(这一点于Internet地址系统比较相似)。当用户发送一个报文时,这些报文就会发送到LAN上所有可用的机器。 在一般情况下,网络上所有的机器都可以“听”到通过的流量,但对不属于自己的报文则不予响应(换句话说,工作站A不会捕获属于工作站B的数据,而是简单的忽略这些数据)。 如果某在工作站的网络接口处于杂收模式,那么它就可以捕获网络上所有的报文和帧,如果一个工作站被配置成这样的方式,它(包括其软件)就是一个嗅探器。 嗅探器可能造成的危害: 嗅探器能够捕获口令 能够捕获专用的或者机密的信息 可以用来危害网络邻居的安全,或者用来获取更高级别的访问权限 事实上,如果你在网络上存在非授权的嗅探器就以为着你的系统已经暴露在别人面前了。(大家可以试试天行2的嗅探功能) 一般我们只嗅探每个报文的前200到300个字节。用户名和口令都包含在这一部分中,这是我们关心的真正部分。工人,也可以嗅探给定接口上的所有报文,如果有足够的空间进行存储,有足够的那里进行处理的话,将会发现另一些非常有趣的东西…… 简单的放置一个嗅探器宾将其放到随便什么地方将不会起到什么作用。将嗅探器放置于被攻击机器或网络附近,这样将捕获到很多口令,还有一个比较好的方法就是放在网关上。如果这样的话就能捕获网络和其他网络进行身份鉴别的过程。这样的方式将成倍地增加我们能够攻击的范围。 关于怎么抵御嗅探器的攻击我就不说了,那是网管们的事儿,有三种方法可能会有所作用: 检测和消灭嗅探器 将数据隐藏,使嗅探器无法发现。 会话加密

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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