2017-04-13 50 views
0

我试图创建我自己的过程来搜索整个数据库的文本字符串,但我不断收到一个动态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 ' [email protected] + 
     ' WHERE ' + @colname + ' IN ' + @SearchString 

    ) 
END 
END 
END 
+3

[为什么“有人可以帮我吗?”不是一个真正的问题?](https://meta.stackoverflow.com/q/284236/62576)和写*我不断收到错误*是一个绝对无用的问题描述。你得到的错误*就在你面前的屏幕上。您绝对没有理由不将它们包含在您的文章中,因此我们也提供了相关信息。你要求我们捐出时间来解决**你的问题;您应该尽可能简单地通过在屏幕上包含**正确的相关详细信息来做到这一点。 –

回答

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 
+0

谢谢Max,这真的很有帮助。我的错误在于我如何执行动态sql语句。在代码中添加更多动态sql的好想法。 –

相关问题