3

別の人が関連する定数を更新してからクエリを実行するだけでよい簡単に更新できるスクリプトを作成する SQL スクリプトを作成しようとしていますが、サブ選択で宣言された変数を使用すると問題が発生します。

これは、宣言された変数がサブ選択の範囲内にないためですが、回避策がないように見えるためです。

現在のコードは次のとおりです。

DECLARE @_logdb varchar(30) = 'nb_tablename';
DECLARE @_sitedb varchar(30) = 'nb_tablename_site';
DECLARE @_backtodate varchar(30) = '2012-10-10';
DECLARE @_sitename varchar(50) = 'bikehaven';

UPDATE
    [@_sitedb].[dbo].[bike] 
SET [bikeStatus] = 'active' 
WHERE bikeID in (
    SELECT 
substring(
    [event], 
    CHARINDEX('bike ID' , [event]) + LEN('bike ID '),
    CHARINDEX(
        ')', 
        [event],
        CHARINDEX('bike ID' , [event])
    ) - (CHARINDEX('bike ID' , [event]) + LEN('bike ID '))
) as 'ID'
from [@_logdb].[dbo].[logs] 
where 
    user_name = 'john' AND 
    event_type = 'Deleted bike' AND 
    CHARINDEX('bike ID' , [event]) > 0 AND 
    date_time > @_backtodate AND 
    siteID = (
        SELECT id 
        from [@_logdb].[dbo].[sites] 
        WHERE site_name = @_sitename
    )
)

実際に問題を引き起こしている 2 つの変数は@_backtodate&@_sitenameですが、これらの変数を実際の文字列に置き換えると、それ[@_sitedb].[dbo].[bike]も問題であるというエラーが表示されることもわかっています。

かなりのグーグル検索を行い、サブクエリに一時テーブルを使用し、SQL を変数自体として定義してからEXECコマンドを実行しようとしましたが、役に立ちませんでした。

編集:クエリ自体を宣言変数に引き出してから実行することで、Andomarの指示に従って変更を適用しました。 @_back to date&の変数エラー@_sitename

解決策: Alexander Fedorenko によって提案された変更により、パズルの最後のビットが得られました。テーブル名は、実際の変数値に対して完全に機能する動的 SQL のパラメーターを介して明示的な置換として使用することはできません。

要するに: - クエリを文字列変数にします。- 発生する必要があるテーブル名の置換は、文字列連結を介して追加できます (つまり、出力文字列は有効なクエリである必要があります) - 置換用の変数パラメーターをストアド プロシージャに渡しますSP_executesql

最終的な作業コードは、Alexander Fedorenkoによって指定されたとおりです。

4

2 に答える 2

2

プロシージャ sp_executesql では、パラメータを使用できます。sp_executesql の使用

DECLARE @_logdb varchar(30) = 'nb_tablename';
DECLARE @_sitedb varchar(30) = 'nb_tablename_site';
DECLARE @_backtodate varchar(30) = '2012-10-10';
DECLARE @_sitename varchar(50) = 'bikehaven';

DECLARE @_SQL nvarchar(max)
SET @_SQL = '
UPDATE
    ' + @_sitedb + '.[dbo].[bike] 
SET [bikeStatus] = ''active'' 
WHERE bikeID in (
    SELECT 
substring(
  [event],
CHARINDEX(''bike ID'' , [event]) + LEN(''bike ID ''),
CHARINDEX(
'')'', 
[event],
CHARINDEX(''bike ID'' , [event])
) - (CHARINDEX(''bike ID'' , [event]) + LEN(''bike ID ''))
) as ''ID''
from ' + @_logdb + '.[dbo].[logs]
where 
user_name = ''john'' AND 
event_type = ''Deleted bike'' AND
CHARINDEX(''bike ID'' , [event]) > 0 AND
date_time > @_backtodate AND
siteID = (
SELECT id 
from ' + @_logdb + '.[dbo].[sites]
WHERE site_name = @_sitename
    )
)'
EXEC sp_executesql @_SQL, N'@_backtodate varchar(30), @_sitename varchar(50)', @_backtodate, @_sitename
于 2012-10-29T09:42:15.943 に答える
2

変数をテーブル名として使用することはできません。したがって、これは機能しません:

from [@_logdb].[dbo].[logs] 

本当に変数テーブル名が必要な場合、唯一のオプションは動的 SQL です。nvarchar(max)SQL で変数を作成し、sp_executesqlまたはで実行しますexec

declare @sql nvarchar(max)
set @sql = 'select * from ' + @tablename
exec (@sql)
于 2012-10-29T08:22:03.087 に答える