SQL Server 2005 动态选择

标签 sql sql-server sql-server-2005

我对 SQL 非常陌生,并且很难学习,所以我会预先警告大家,我的错误很可能是显而易见的 - 不要以为我知道我在做什么!这是 SQL Server 2005 中的内容。

编辑:下面的代码无意中产生了误导; my_table 不是表,而是 View 。所述 View 将两个模式中的信息缝合在一起,对其其中一列使用 LEFT OUTER JOIN,对其中四列使用 stuff((SELECT.....)),当我发布此 View 时,没有两行的列共享相同的数据;我已将其更改为使用 SELECT DISTINCT。

我正在尝试编写一个函数,该函数将名称的四个部分(第一个、中间、最后一个和标题)作为参数,并使用 LIKE 根据这 4 个部分对给定表运行选择。这种简单的方法返回正确的结果:

ALTER FUNCTION [my_schema].[my_table] (
    @first NVARCHAR(max) = null
    ,@middle NVARCHAR(max) = null
    ,@last NVARCHAR(max) = null
    ,@title NVARCHAR(max) = null
)
RETURNS TABLE AS RETURN(
    SELECT DISTINCT  
        l.foo,
        l.bar,
        l.spam
    FROM my_database.my_schema.my_table l
    WHERE 
        l.FirstName like ISNULL('%'+@last+'%', '%')
        AND l.LastName like ISNULL('%'+@first+'%', '%')
        AND l.MiddleName like ISNULL('%'+@middle+'%', '%')
        AND l.TitleName like ISNULL('%'+@title+'%', '%')
);

问题是它非常慢。我能看到的缓慢的最明显原因是与“%”进行比较的非常愚蠢的行为;我希望 SQL 通过根本不进行比较来响应 NULL。我还没有想出办法来做到这一点;我提出的每一个解决方案都会遇到有效的 SQL 语法的障碍。

我的问题是“当适当的变量为空时,如何避免与 '%' 进行 LIKE 比较?”。我在这里尽可能反对在任何上下文中使用 EXEC,因为我从野外获取用户输入并返回潜在的敏感数据,并且我希望对注入(inject)尽可能偏执 - 这四个变量是野外输入,我想尽可能少地信任他们。

编辑:我已经完成了速度测试,并得出结论,避免额外的“喜欢”并没有任何有意义的程度的帮助。我欢迎任何关于实际实现加速的建议,并且一旦我重新考虑了如何将其组合在一起,我可能会很快沿着这些思路提出一个新问题。

最佳答案

我不确定您是否会获得更好的性能,但我认为您的Where语句中的以下Case语句也将起作用。

WHERE l.FirstName LIKE CASE WHEN @first IS NULL THEN  '%' ELSE '%' + @First + '%' END
AND l.LastName LIKE CASE WHEN @last IS NULL THEN '%' ELSE '%' + @Last + '%' END 
AND ...

关于SQL Server 2005 动态选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21142297/

相关文章:

sql - OR 语句 SQL 的优先级

sql - 使用 powershell 为单个事务中的多个文件调用 sqlcmd

tsql - SQL Server 2005 用 0 填充数据透视表

mysql - 在单个 SQL 查询中修剪、转换和比较来自 SQL DB 的字符串

sql - SQL触发器: On update of primary key,如何确定哪个 “deleted”记录对应于哪个 “inserted”记录?

Python sqlite3 如果 executemany() 中途遇到完整性错误会怎样?

c++ - 处理 360 度范围的最佳方式

mysql - VPS无法通过socket连接本地MySQL服务器

sql-server - 我可以使用 SQL Server 2012 Express 来使用 SSDT/BIDS/SSIS 吗?

sql-server - 如何在 SQL 中将文本列转换为日期时间