menu

天魔窟

勇往直前

Avatar

关于 SQL 的 IN 查询,逗号串的传入……

首先对 MSN Explorer 9.0 表示寒,界面固然豪华,不过似乎不够稳定,已经遇到几次无故的突然 crash 关闭,特别是在上 zol 时,顺便 874 zol,广告 toooo many!!!

写类似 SELECT ... FROM ... WHERE ID IN (1, 2, 4, 16) 这样的 SQL 时,IN 后面的逗号分隔参数是需要写死的——假如在存储过程中,IN 后面的东西是不能用 @param 的形式传参数的——这个参数应该是什么类型呢?呵呵~问题就是这个。是否这样的情况下就不能用存储过程了呢?

今天看了 4Guys 的文章,有一篇就是讨论的这个问题:Creating a User Defined Function in SQL for Comma-Delimited Searches。很长的文章,废话不少,当然,说的很详细了,初学者也能看得明白。文中所提出的技术,是创建一个自定义函数,把以 @param 形式传入的逗号分隔串弄成一个表,然后用 SELECT ... FROM ... WHERE ID1 IN (SELECT ID2 FROM tempTable) ... 的形式(也是 IN 所支持的另一种用法),这里的 tempTable 就是由文中所写的自定义函数创建。

我觉得这样写反而比较麻烦和混乱,大量的 charindex 和 len 函数……文中提到的一个链接也是讨论这个问题,那篇文章的办法就是传统的拼接字符串(在 SP 中拼接),然后 exec() 这个string,呵呵……也许还是存在安全问题吧?

MSN9有截图么?

SQL嵌套对数据库服务器服务器的CPU是否要求很高呢?

ADODB.Recordset 错误 '800a0bcd'

BOF 或 EOF 中有一个是“真”,或者当前的记录已被删除,所需的操作要求一个当前的记录。

//global.asa,行45

在执行图一中后两个SQL语句前,必须打开“显示执行计划”开关,按CTRL+K组合键,按F5执行后,返回同样的记录,查询成本却相去甚远,为什么呢?使用EXISTS的查询在执行计划中使用了NESTED LOOPS与LEFT SEMI JOIN等运算符;而使用IN的查询在执行中使用了HASH MATCH与RIGHT SEMI JOIN运算符。 在SQLSERVER的联机帮助中,输入NESTED LOOP等可以看到它们的说明。

关于嵌套循环联接
嵌套循环联接也称为嵌套迭代,它将一个联接输入用作外部输入表(显示为图形执行计划中的顶端输入),将另一个联接输入用作内部(底端)输入表。外部循环逐行消耗外部输入表。内部循环为每个外部行执行,在内部输入表中搜索匹配行。最简单的情况是,搜索时扫描整个表或索引;这称为单纯嵌套循环联接。如果搜索时使用索引,则称为索引嵌套循环联接。如果将索引生成为查询计划的一部分(并在查询完成后立即将索引破坏),则称为临时索引嵌套循环联接。查询优化器考虑所有这些不同形式。如果外部输入很小而内部输入很大且预先创建了索引,则嵌套循环联接尤其有效。在许多小事务中(如那些只影响较小的一组行的事务),索引嵌套循环联接远比合并联接和哈希联接优越。但在大查询中,嵌套循环联接通常不是最佳选择。

了解哈希联接
哈希联接有两种输入:生成输入和探测输入。查询优化器指派这些角色,使两个输入中较小的那个作为生成输入。
哈希联接可用于许多类型的集合匹配操作:内联接,左向外联接、右向外联接和完整外联接,左向半联接和右向半联接、交集、联合和差分。而且,哈希联接的变化形式能够进行重复项删除和分组操作(如 SUM(salary) GROUP BY department)。这些修改对生成和探测角色只使用一个输入。
与合并联接相似,只有当联接谓词中至少有一个等效 (WHERE) 子句时才能使用哈希联接。然而,联接一般用于重组合由主键和外键之间的等效谓词表达的关系,因此大多数联接至少有一个等效子句。用等效谓词表达的列集合称为哈希键,因为这些列有助于哈希函数。还可以有附加的谓词,并且可以将这些谓词取值为驻留谓词以与哈希值比较分开。哈希键可以是表达式,只要能从单个行中的列对其进行排它计算。在分组操作中,按列表分组的列是哈希键。在交集等集合操作中以及删除复制项时,哈希键由所有列组成。
内存中的哈希联接
哈希联接先扫描或计算整个生成输入,然后在内存中生成哈希表。根据为哈希键计算出的哈希值,将每行插入哈希存储桶。如果整个生成输入比可用内存少,则可以将所有行都插入哈希表中。生成阶段后接着是探测阶段。一次一行地对整个探测输入进行扫描或计算,并为每个探测行计算哈希键的值,扫描相应的哈希存储桶并生成匹配项。
Grace 哈希联接
如果生成输入不适合内存,哈希联接将分步进行。每一步都包括生成阶段和探测阶段。首先,消耗整个生成和探测输入并(使用哈希键上的哈希函数)将其分区为多个文件。这类文件的数目称为分区输出端。通过使用哈希键上的哈希函数,可以保证任意两个联接记录必在相同的文件对中。因此,联接两个大输入的任务简化为相同任务的多个较小的实例。然后将哈希联接应用于每对分区文件。
递归哈希联接
如果生成输入非常大,以至于标准外部合并排序的输入需要多个合并级别,则需要多个分区步骤和多个分区级别。如果只有某些分区较大,则只需对这些分区使用附加的分区步骤。为使所有的分区步骤尽可能快,将使用大的异步 I/O 操作以便单个线程就能使多个磁盘驱动器繁忙工作。

说明 如果生成输入较大但并不比可用内存大很多,则内存中的哈希联接和 Grace 哈希联接的元素将合并成一个步骤,产生混合哈希联接。
在优化过程中并不总能确定使用什么样的哈希联接。因此,Microsoft® SQL Server™ 2000 开始时使用内存中的哈希联接,然后根据生成输入的大小逐渐转换到 Grace 哈希联接和递归哈希联接。
如果优化器错误地预计两个输入中哪个较小并由此确定哪个作为生成输入,生成角色和探测角色将动态逆转。哈希联接确保使用较小的溢出文件作为生成输入。这一技术称为角色逆转

近日访问expert.csdn.net经常导致浏览器死亡,等待半天(约四小时仍不见苏醒)

评论已关闭