有人可以帮助我一些动态SQL知识

时间:2017-04-13 23:18:28

标签: sql-server stored-procedures dynamic-sql

我正在尝试创建自己的程序来搜索数据库中的文本字符串,但我不断收到动态SQL相关错误。我知道还有其他可用的程序,但我只是想尝试创建自己的程序来练习。已经有一段时间了,我仍然无法弄明白......

    USE AdventureWorks2014
GO

SET NOCOUNT ON;
DECLARE @tablename nvarchar(max) = ''
DECLARE @colname nvarchar(128)
DECLARE @searchstring nvarchar(max) = 'Ken'
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
IF OBJECT_ID('tempdb..#Dynamic') IS NOT NULL
DROP TABLE #Dynamic 

CREATE TABLE #Results (tablename nvarchar(max), colname nvarchar(128))
CREATE TABLE #Dynamic (colname nvarchar(128))

WHILE @tablename IS NOT NULL
BEGIN
SET @colname = ''
SET @tablename = (
                    SELECT MIN(SCHEMA_NAME(ta.schema_id) + '.' + ta.name)
                        FROM sys.tables ta
                            WHERE SCHEMA_NAME(ta.schema_id) + '.' + ta.name > @tablename
                                AND ta.object_id IN (
                                                        SELECT DISTINCT(c.object_id)
                                                        FROM sys.columns c
                                                            JOIN sys.types t
                                                                ON c.user_type_id = t.user_type_id
                                                                AND t.name IN ('varchar', 'nvarchar','char','name')

                                                    )
                    )
WHILE (@tablename IS NOT NULL) AND (@colname IS NOT NULL)
BEGIN
SET @colname = (
                    SELECT MIN(c.name)
                    FROM sys.columns c
                    JOIN sys.types t
                    ON c.user_type_id = t.user_type_id
                    AND t.name IN ('nvarchar', 'varchar','char','name')
                    AND c.object_id = OBJECT_ID(@tablename)
                    and c.name > @colname
                )

IF @colname IS NOT NULL
BEGIN
SET @tablename = QUOTENAME(@tablename)
SET @colname = QUOTENAME(@colname)
INSERT INTO #Results 
EXEC
    (
        'SELECT '+ @colname + 
        ' FROM ' +@TableName +
        ' WHERE ' + @colname + ' IN ' + @SearchString

    )
END
END
END

1 个答案:

答案 0 :(得分:0)

在这里 - 我觉得这很有效。我做了几处更改,但请注意我将查询构建为字符串并使用sp_executesql来运行它们。这样做的好处是您可以打印输出并在另一个窗口中执行它以确保它正常工作。

有一些打印声明 - 我用它们来检查每个部分,因为我逐步完成了你的脚本。我让他们离开了,所以你可以看到一次检查一件的思维过程。

USE AdventureWorks2012
GO

SET NOCOUNT ON;
DECLARE @tableplusschema nvarchar(max) = ''
DECLARE @tablename nvarchar(max) = ''
DECLARE @colname nvarchar(128)
DECLARE @qry nvarchar(max)
DECLARE @searchstring nvarchar(max) = 'Ken'
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
IF OBJECT_ID('tempdb..#Dynamic') IS NOT NULL
DROP TABLE #Dynamic 
IF OBJECT_ID('tempdb..#TableName') IS NOT NULL
DROP TABLE #TableName
IF OBJECT_ID('tempdb..#ColName') IS NOT NULL
DROP TABLE #ColName

CREATE TABLE #TableName (tableplusschema nvarchar(max))
CREATE TABLE #ColName (colname nvarchar(max))
CREATE TABLE #Results (tablename nvarchar(max), colname nvarchar(128), value nvarchar(max))
CREATE TABLE #Dynamic (colname nvarchar(128))

WHILE @tableplusschema IS NOT NULL
BEGIN
    SET @colname = ''
    DELETE FROM #TableName;
    SET @qry = '    
                INSERT INTO #TableName (tableplusschema) SELECT MIN(SCHEMA_NAME(ta.schema_id) + ''.'' + ta.name)
                FROM sys.tables ta
                WHERE SCHEMA_NAME(ta.schema_id) + ''.'' + ta.name > ''' + REPLACE(REPLACE(@tableplusschema, '[', ''), ']', '') + '''
                AND ta.object_id IN (
                                        SELECT DISTINCT(c.object_id)
                                        FROM sys.columns c
                                        JOIN sys.types t
                                        ON c.user_type_id = t.user_type_id
                                        AND t.name IN (''varchar'', ''nvarchar'',''char'',''name'')
                                    )
                '
    print @qry
    exec sp_executesql @qry
    SELECT top 1 @tableplusschema = tableplusschema, @tablename = right(tableplusschema, len(tableplusschema) - charindex('.', tableplusschema)) from #TableName
    print @tableplusschema
    print @tablename

    WHILE (@tableplusschema IS NOT NULL) AND (@colname IS NOT NULL)
    BEGIN
        DELETE FROM #ColName;
        SET @qry = 'INSERT INTO #ColName (colname) SELECT MIN(c.name)
                    FROM sys.columns c
                    JOIN sys.types t
                    ON c.user_type_id = t.user_type_id
                    AND t.name IN (''nvarchar'', ''varchar'',''char'',''name'')
                    AND c.object_id = OBJECT_ID(''' + REPLACE(REPLACE(@tableplusschema, '[', ''), ']', '') + ''')
                    and c.name > ''' +  REPLACE(REPLACE(@colname, '[', ''), ']', '') + ''''
        print @qry
        exec sp_executesql @qry

        SELECT TOP 1 @colname = REPLACE(REPLACE(colname, '[', ''), ']', '') FROM #ColName

        print @colname
        IF @colname IS NOT NULL 
        BEGIN
            --SET @tableplusschema = QUOTENAME(@tableplusschema)
            SET @colname = QUOTENAME(@colname)

            SET @qry = 'INSERT INTO #Results (tablename, colname, value) SELECT '''+ @tableplusschema + ''', ''' + @colname + 
                    ''', ' + @colname + ' FROM ' + REPLACE(REPLACE(@tableplusschema, '[', ''), ']', '') +
                    ' WHERE ' + @colname + ' LIKE ''%' + @SearchString + '%'''
            print @qry
            exec sp_executesql @qry
        END
    END
END

SELECT * FROM #Results