为什么此查询中的变量不能返回任何值?

时间:2019-01-02 21:45:01

标签: sql-server tsql

我正在使用它来搜索大型数据库,以查找我要搜索的列名存在的表。也许我把这个复杂化了,但是我希望能够通过输入一次条件然后覆盖存在的所有变体来搜索数据库。我必须为数百个列名称执行此操作,而一遍又一遍地输入所有三种可能性将很痛苦。

我尝试在查询的 WHERE 部分中不使用别名,但最终遇到这样的边界错误:

  

多重标识…可能无法绑定

DECLARE 
    @searchColumn varchar
SELECT 
    a.name AS TableName, 
    b.name AS ColumnName
FROM sys.columns b
JOIN sys.tables a ON b.object_id = a.object_id
WHERE 
    @searchColumn = 'inst_key'
    and b.name LIKE @searchColumn
            or b.name LIKE concat('%',@searchColumn)
            or b.name LIKE concat('%',@searchColumn,'%')
            or b.name LIKE concat(@searchColumn,'%')
ORDER BY
    a.name asc, b.name asc;

我希望获得此查询以返回所有表和列的列表,这些表和列返回与@searchColumn变量匹配的内容。

3 个答案:

答案 0 :(得分:1)

您的查询似乎没问题(它可以在我的机器上运行;)。问题可能出在变量声明上。尝试使用VARCHAR( 128 )。

尽管您的WHERE部分看起来有些奇怪, 以下代码可用于我的SQL Server 2017:

DECLARE 
    @searchColumn varchar(128) = 'YOUR_FIELD_NAME_HERE'

SELECT 
    a.name AS TableName, 
    b.name AS ColumnName
FROM sys.columns b
JOIN sys.tables a ON b.object_id = a.object_id
WHERE 
    @searchColumn = 'inst_key'
    and b.name LIKE @searchColumn
            or b.name LIKE concat('%',@searchColumn)
            or b.name LIKE concat('%',@searchColumn,'%')
            or b.name LIKE concat(@searchColumn,'%')
ORDER BY
    a.name asc, b.name asc;

编辑:

我也在SQL Server 2012上尝试过,效果很不错。

修改2: 也许以下是您正在寻找的东西?

DECLARE 
    @searchColumn varchar(128) = 'inst_key'

SELECT 
    a.name AS TableName, 
    b.name AS ColumnName
FROM sys.columns b
JOIN sys.tables a ON b.object_id = a.object_id
WHERE 
    b.name LIKE concat('%',@searchColumn,'%')
ORDER BY
    a.name asc, b.name asc;

答案 1 :(得分:1)

问题在于您正在声明一个变量且未分配任何值(也未声明其长度)。更改此:

DECLARE @searchColumn varchar

对于

DECLARE @searchColumn varchar(100) = 'ValueToSearch' -- Put the searched column partial name here

然后,您还想删除查询中的硬编码值检查。 WHERE子句存在一些问题,我将在此处详细说明:

WHERE 
    @searchColumn = 'inst_key'
    and b.name LIKE @searchColumn
            or b.name LIKE concat('%',@searchColumn)
            or b.name LIKE concat('%',@searchColumn,'%')
            or b.name LIKE concat(@searchColumn,'%')
  • 您正在混合使用ANDOR运算符而没有括号(引擎可能不会使用您希望使用的优先级)。
  • 仅当变量的值为'inst_key'时,第一个表达式才为true;由于您未分配任何值(值为NULL),因此第一个表达式始终为false。
  • LIKE特殊字符%将匹配0到N个字符,因此您所有的4个LIKE表达式都可以简化为LIKE '%' + @searchColumn + '%'。如果要转义变量的NULL值,只需使用ISNULL(@searchColumn, '')

这是固定查询:

DECLARE @searchColumn varchar(100) = 'PartialColumnNameToSearch'

SELECT 
    a.name AS TableName, 
    b.name AS ColumnName
FROM sys.columns b
JOIN sys.tables a ON b.object_id = a.object_id
WHERE 
    b.name LIKE '%' + ISNULL(@searchColumn, '') + '%'
ORDER BY
    a.name asc, b.name asc;

如果变量的值为NULL,则LIKE将得出'%%',并且它将匹配所有记录(NULL值除外,但是任何表都不能包含{{ 1}}作为列名。


错误消息:

  

多重标识…可能无法绑定

指出没有一个别名列引用(或服务器/数据库)。这不是查询的问题,因此我假设您在收到此错误消息后编辑了发布的SQL。

答案 2 :(得分:0)

错误是因为您在查询中有一个赋值

我想你想要这个:

WHERE CONTAINS(b.name, 'inst_key')

WHERE CONTAINS(b.name, @searchColumn)

如果您不能使用contains,那么它应该更快-

WHERE b.name LIKE ('%' || @searchColumn || '%')

可以使用-您不需要3个版本。 %将匹配0个字符。
根据所使用的平台,使用正则表达式可能会更快。