1

あるテーブル (またはストアド プロシージャ) から一時テーブルにデータを挿入しようとしています。一時テーブルの列数がソース テーブルの列数と一致しません。ソースデータを最初の列から一時テーブルに挿入し、残りの列は文字列列を空にします。

つまり、Tempテーブルに 10 列があり、ソース テーブルに 3 列しかない場合、最初の 3 列を一時テーブルに挿入すると、残りの 7 列は空または null になります。

例 :

CREATE TABLE #VarTemp(Col1 nvarchar(256), Col2 nvarchar(256), Col3 nvarchar(256),
                      Col4 nvarchar(256), Col5 nvarchar(256), Col6 nvarchar(256),
                      Col7 nvarchar(256), Col8 nvarchar(256), Col9 nvarchar(256),
                      Col10 nvarchar(256))

INSERT into #VarTemp 
    EXEC sp_FindStringInTable 'Nareshbhai%', 'dbo', 'UserstoClean';

SELECT * FROM #VarTemp 

別々に実行すると

EXEC sp_FindStringInTable 'Nareshbhai%', 'dbo', 'UserstoClean';

私は得ています

 Constitid  FirstName   LastName    email   status          pincode
 3151502    Nareshbhai  Desai   desanar@iit.edu Inactive    desai

エラーは

エラーが発生しました。オブジェクトが存在することを確認してください。(影響を受ける行はありません)

メッセージ 0、レベル 11、状態 0、行 0
現在のコマンドで重大なエラーが発生しました。結果がある場合は、破棄する必要があります。

sp_FindStringInTable

ALTER PROCEDURE [dbo].[sp_FindStringInTable]
    @stringToFind VARCHAR(100), @schema sysname, @table sysname 
AS 
    DECLARE @sqlCommand VARCHAR(8000) 
    DECLARE @where VARCHAR(8000) 
    DECLARE @columnName sysname 
    DECLARE @cursor VARCHAR(8000) 

BEGIN TRY 
   SET @sqlCommand = 'SELECT * FROM ' + @schema + '.' + @table + ' WHERE' 
   SET @where = '' 

   SET @cursor = 'DECLARE col_cursor CURSOR FOR 
      SELECT COLUMN_NAME 
      FROM ' + DB_NAME() + '.INFORMATION_SCHEMA.COLUMNS 
      WHERE TABLE_SCHEMA = ''' + @schema + ''' 
        AND TABLE_NAME = ''' + @table + ''' 
        AND DATA_TYPE IN (''char'', ''nchar'', ''ntext'', ''nvarchar'', ''text'', ''varchar'')' 

   EXEC (@cursor) 

   OPEN col_cursor    
   FETCH NEXT FROM col_cursor INTO @columnName    

   WHILE @@FETCH_STATUS = 0    
   BEGIN    
       IF @where <> '' 
           SET @where = @where + ' OR' 

       SET @where = @where + ' ' + @columnName + ' LIKE ''' + @stringToFind + '''' 
       FETCH NEXT FROM col_cursor INTO @columnName    
   END    

   CLOSE col_cursor    
   DEALLOCATE col_cursor  

   SET @sqlCommand = @sqlCommand + @where 
   --PRINT @sqlCommand 
   EXEC (@sqlCommand)  
END TRY 
BEGIN CATCH 
   PRINT 'There was an error. Check to make sure object exists.' 
   IF CURSOR_STATUS('variable', 'col_cursor') <> -3 
   BEGIN 
       CLOSE col_cursor    
       DEALLOCATE col_cursor  
   END 
END CATCH
GO
4

1 に答える 1

1

ここに表示されるように、これは機能しません。

''SELECT * FROM' + @スキーマ + '.' + @テーブル + ' WHERE' '

動的 SQL をロードして、テーブル内の ALL COLUMNS の列結果を生成しています。これらのすべてのテーブルが、明示的に定義したのと同じ 10 列のみを具体的に持っていない限り、これは壊れます。テーブルを動的に選択して一時テーブルにする必要があるのはなぜですか? 特定のデータ型のテーブルを見つけて上位 10 件の結果を選択するだけの場合は、これでうまくいきます。

declare @Temp table ( id int identity, val varchar(64) )

--insert into @Temp
select distinct
  'select top 10 * from ' + s.name + '.' + t.name

from sys.tables t (nolock) 
    join sys.schemas s (nolock) on t.schema_id = s.schema_id
    join sys.columns c (nolock) on t.object_id = c.object_id
    join sys.types ty (nolock) on c.system_type_id = ty.system_type_id
        and ty.name in ('char', 'nchar', 'ntext', 'nvarchar')  --etc, if you want to find specific column types listed only

declare @Current int = 1, @max int, @SQL varchar(max);

select @Max = max(id) from @Temp

while @Current <= @Max
BEGIN
    select @SQL = val from @Temp where id = @Current

    exec (@SQL)

    set @Current += 1;
END
于 2013-01-16T23:30:47.550 に答える