2017-04-13 2 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を使用してそれらを実行しました。その利点は、出力を印刷して別のウィンドウで実行して、それが動作することを確認できることです。

いくつかの印刷ステートメントがあります - 私はあなたのスクリプトを進めるにつれて、それらを使って各部分をチェックしました。私はそれらを残しましたので、あなたは一度に1つの部分をチェックする思考プロセスを見ていることがあります。

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

ありがとうマックス、これは本当に役に立ちます。私の間違いは、動的SQL文をどのように実行していたかにあります。コードに動的SQLを追加することをお勧めします。 –

関連する問題