ストアド プロシージャに渡されたパラメータをクエリし、パラメータの文字列を作成せずに XML として返し、それを xml としてキャストする方法はありますか? 毎回物理的にコーディングする必要なく、ほとんどの SP で機能する一般的なものを探していますか?
ベリファイ固有の情報にアクセスして変更する一連のストアド プロシージャがあります。SP の最後に、SP の名前と、SP の呼び出しに使用されたパラメーター (xml 形式) をログ テーブルに挿入します。SP の名前を取得する方法と、SP のパラメーターのリストを取得する方法を知っています。私が欲しいのは、渡されたパラメーターの実際の値に沿って、すべてを XML にマッシュアップする方法です。
各パラメーターを手動でコーディングせずに、これを行うものを探しています:
DECLARE @L_Data varchar(1500)
SET @L_Data = '<parms>' +
CASE WHEN @ParamRegStationID IS NULL THEN ''
ELSE ',@ParamRegStationID=''' + Convert(varchar, @ParamRegStationID) + '''' END +
CASE WHEN @ParamScheduleID IS NULL THEN ''
ELSE ',@ParamScheduleID=''' + Convert(varchar, @ParamScheduleID) + '''' END +
CASE WHEN @ParamPatientID IS NULL THEN ''
ELSE ',@ParamPatientID=''' + Convert(varchar, @ParamPatientID) + '''' END +
CASE WHEN @ParamHISPatientID IS NULL THEN ''
ELSE ',@ParamHISPatientID=''' + @ParamHISPatientID + '''' END +
CASE WHEN @ParamEvent IS NULL THEN ''
ELSE ',@ParamEvent=''' + @ParamEvent + '''' END +
'</parms>'
これは機能せず、私が望んでいるほどエレガントではありません。ただし、これは私が最終的に到達しようとしていることを示す例です。一時テーブルを作成しますが、パラメーターを列として追加しないため、後で XML として抽出できます。
ALTER PROC uspTest
@ParamID as bigint=null,
@ParamXYZ as varchar(255)=null
as
-- PROC Does whatever it is going to do ....
DECLARE @ProcName varchar(128), @ParmName varchar(128), @ParmType varchar(128), @ParmLen int,
@ParmSQL varchar(1000)
select @ProcName=OBJECT_NAME(@@PROCID)
--select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE='PROCEDURE' and ROUTINE_NAME=@ProcName
DECLARE csrParms CURSOR
FOR
select PARAMETER_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME=@ProcName and PARAMETER_MODE='IN'
ORDER BY ORDINAL_POSITION
FOR READ ONLY
OPEN csrParms
FETCH NEXT FROM csrParms
INTO @ParmName, @ParmType, @ParmLen
CREATE TABLE #Parms(ID int identity(1,1), Created DateTime)
INSERT INTO #Parms select GETDATE()
WHILE @@FETCH_STATUS = 0
BEGIN
-- GET Parm value and format as xml attribute to save parm
SET @ParmSQL = 'ALTER TABLE #Parms add ' + @ParmName + ' varchar(' + CAST(ISNULL(@ParmLen, 128) as varchar(128)) + ') NULL '
print @ParmSQL
EXEC (@ParmSQL)
SET @ParmSQL = 'UPDATE #Parms SET ' + @ParmName + ' = ''????'''
print @ParmSQL
--EXEC (@ParmSQL)
FETCH NEXT FROM csrParms
INTO @ParmName, @ParmType, @ParmLen
END
SET @ParmSQL = CAST((select * from #Parms FOR XML RAW) as varchar(1000))
select @ParmSQL
CLOSE csrParms
DEALLOCATE csrParms
これは私が探しているものに近いです。??? を置き換える方法を知る必要があります。ただし、パラメーターの現在の値を動的に使用します。
ALTER PROC uspTest
@ParamID as bigint=null,
@ParamXYZ as varchar(255)=null
as
-- PROC Does whatever it is going to do ....
DECLARE @ProcName varchar(128), @ParmName varchar(128), @ParmType varchar(128), @ParmLen int,
@ParmSQL varchar(1000)
select @ProcName=OBJECT_NAME(@@PROCID)
--select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE='PROCEDURE' and ROUTINE_NAME=@ProcName
set @ParmSQL =
' CREATE TABLE #Parms(ID int identity(1,1), Created DateTime, ' +
STUFF((select (', ' + REPLACE(PARAMETER_NAME,'@','') + ' varchar(' + CAST(ISNULL(CHARACTER_MAXIMUM_LENGTH, 128) as varchar(128)) + ') NULL ')
from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='uspTest' and PARAMETER_MODE='IN'
order by ORDINAL_POSITION for XML path(''), type).value('.', 'varchar(max)'), 1, 2, '')
+ ');
' + 'INSERT INTO #Parms (Created) select GETDATE(); ' + STUFF((select (';
UPDATE #Parms SET ' + REPLACE(PARAMETER_NAME,'@','') + ' = ''???''')
from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='uspTest' and PARAMETER_MODE='IN'
order by ORDINAL_POSITION for XML path(''), type).value('.', 'varchar(max)'), 1, 2, '')
+ ';
select CAST((select * from #Parms FOR XML RAW) as varchar(1000));'
print @ParmSQL
EXEC (@ParmSQL)
次のようにprocを実行すると:
EXEC uspTest 1, 'test'
戻り値:
<row ID="1" Created="2012-04-20T09:44:43.700" ParamID="???" ParamXYZ="???"/>
プリントアウト:
CREATE TABLE #Parms(ID int identity(1,1), Created DateTime, ParamID varchar(128) NULL , ParamXYZ varchar(255) NULL );
INSERT INTO #Parms (Created) select GETDATE();
UPDATE #Parms SET ParamID = '???';
UPDATE #Parms SET ParamXYZ = '???';
select CAST((select * from #Parms FOR XML RAW) as varchar(1000));