我编写了一个存储过程:
在最后一个过程返回表,其中包含表名和行ID,找到了密钥。
这是代码:
--Search keys in tables
CREATE PROCEDURE [dbo].[Search_All]
(
@SearchKeys nvarchar(50), --Keys to search separated by ','
@ToSearch varchar(200) --Tables to search in separated by ',' with colums after ':' separated by '.'
)
AS
BEGIN
--create table with found values
CREATE TABLE #Results (TargetId int, DBName varchar(20))
--Split SearchKeys to Keys
WHILE LEN(@SearchKeys) > 0
BEGIN
DECLARE @Key NVARCHAR(25)
IF CHARINDEX(',',@SearchKeys) > 0
SET @Key = SUBSTRING(@SearchKeys,0,CHARINDEX(',',@SearchKeys))
ELSE
BEGIN
SET @Key = @SearchKeys
SET @SearchKeys = ''
END
--Split ToSearch to Tables
WHILE LEN(@ToSearch) > 0
BEGIN
DECLARE @TableAndColums VARCHAR(200)
IF CHARINDEX(',',@ToSearch) > 0
SET @TableAndColums = SUBSTRING(@ToSearch,0,CHARINDEX(',',@ToSearch))
ELSE
BEGIN
SET @TableAndColums = @ToSearch
SET @ToSearch = ''
END
SET @ToSearch = REPLACE(@ToSearch,@TableAndColums + ',' , '')
--Split @TableAndColums to Table and Colums
--Select Table
DECLARE @Table VARCHAR(25)
SET @Table = SUBSTRING(@TableAndColums,0,CHARINDEX(':',@TableAndColums))
SET @TableAndColums = REPLACE(@TableAndColums,@Table + ':' , '')
--Split to Colums
WHILE LEN(@TableAndColums) > 0
BEGIN
DECLARE @Column VARCHAR(25)
IF CHARINDEX('.',@TableAndColums) > 0
SET @Column = SUBSTRING(@TableAndColums,0,CHARINDEX('.',@TableAndColums))
ELSE
BEGIN
SET @Column = @TableAndColums
SET @TableAndColums = ''
END
BEGIN
--insert result in to #Results table
INSERT INTO #Results
EXEC
(
'SELECT ' + @Table + '.Id AS ''TargetId'', '''+@Table+''' AS ''DBName''
FROM ' + @Table +
' WHERE ' + @Column + ' LIKE N''%' + @Key + '%'''
)
END
SET @TableAndColums = REPLACE(@TableAndColums,@Column + '.' , '')
END
END
SET @SearchKeys = REPLACE(@SearchKeys,@Key + ',' , '')
END
--return found values
SELECT DISTINCT TargetId , DBname FROM #Results
END
由于某种原因,它只搜索忽略所有其余键的第一个键。我不明白为什么会这样。请帮忙!
答案 0 :(得分:1)
我在这里警告你的第一件事是你的程序对注射攻击是敞开的。注入攻击本身就是一个广泛的话题。如果您有兴趣,我建议您阅读这篇文章。如果你确实需要这种类型的接口(即你不能使用静态类型的SQL或类似于Entity Framework的东西来处理你的查询),你必须必须确保在运行时执行任何字符串(例如@column,@ table,@ key)是参数化或括号。如所写的,当输入的表不包含ID列或者当输入的列不存在时,该过程也将失败。
http://www.sommarskog.se/dynamic_sql.html
就你如何进行字符串拆分而言,我会看下面的文章。虽然没有办法消除循环每个表的需要,但是通过使用像本文中提到的字符串夹板函数将所有搜索字符串放入表中,您可以一次搜索单个表上的所有搜索条件。像这样:
select *
from #SearchConditions a
inner join dbo.TargetTable b
on b.Name like '%' + a.SearchKey + '%'