有没有办法查询传递给存储过程的参数并将它们作为 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="???" 参数XYZ="???"/>
打印出来:
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));