【发布时间】:2013-06-02 19:35:08
【问题描述】:
我正在尝试创建一个通用更新过程。这个过程的重点是我们希望能够跟踪表中发生的所有事情。如果更新了一条记录,我们需要能够知道谁更改了该记录,它最初是什么,更改后是什么以及更改发生的时间。我们只在必须承担责任的最重要的桌子上这样做。
现在,我们通过结合使用 Web 服务器编程和 SQL Server 命令来实现这一点。
我需要利用我们目前拥有的东西,制作一个仅 SQL 的版本。
所以,这是我需要的要求:
原来的sp叫做UpdateWithHistory。现在,它需要 4 个参数,都是 varchar(也可以是 nvarchar,没关系)。它们是表名、主键字段、主键值和逗号分隔的字段和值列表,格式为 field='value',field1='value1'...等。
在后台,我们有一个映射表,用于将字符串表名映射到实际表。
在存储过程中,我尝试了OPENROWSET、exec()、select into、xml等方法的各种组合。似乎没有一个工作。
所以基本上,我必须能够从 4 个提供的参数中动态生成一个简单的选择语句(没有连接或其他复杂的选择内容),然后将该查询的结果存储在一个表中。由于它是动态的,我不知道要查询的字段数量,也不知道它们将是什么数据类型。
我尝试了 select into 因为它会自动创建一个包含适当字段和数据类型的表,但它不能与 exec 命令一起使用。我也试过了
exec sp_executeSQL @SQL, N'@output xml output', @resultXML output
@resultXML 是 XML 数据类型,@SQL 是 sql 命令。无论我做什么,@resultXML 总是以 null 结束。我也尝试了 xml 路由,因为我知道“FOR XML Path”总是返回一列,但我不能在 insert into 语句中使用它......
该语句输出将用于确定更新前的原始值。
我想一旦我克服了这个障碍,剩下的就是小菜一碟了。有人有什么想法吗?
所以这是我终于开始工作的代码,虽然我不想使用全局表,所以我很乐意接受不同的答案......
DECLARE @curRecordString varchar(max) = 'SELECT * into ##TEMP_TABLE FROM SOMEDB.dbo.' + @tbl + ' WHERE ' + @prikey + ' = ''' + @prival + ''' '
exec(@curRecordString)
基本上,如前所述,我需要动态构建一个 sql 查询,然后存储运行查询的结果,以便以后可以访问它。我更愿意将它存储为 XML 数据类型,因为稍后我将使用 XQuery 来解析和比较节点。在上面的代码中,我使用了一个全局临时表(我知道这并不理想)来存储查询结果,以便我的过程的其余部分可以访问数据。
就像我说的,我不喜欢这种方法,但希望其他人能想出更好的方法,让我能够动态构建 SQL 查询、运行它、存储结果,以便我以后可以访问结果存储过程。
【问题讨论】:
-
你为什么不直接使用Microsoft SQL Server Change Data Capture?
-
第 1 号,不知道那是什么。第二,我公司使用的系统已有 10 多年的历史,最初是在经典的 asp 和 VBScript 新出现时设计的。所以我们所做的任何事情都需要符合这个旧系统。
-
我点击了你的链接,看起来它在大多数情况下都可以工作,但不是我的,因为我的老板想在他多年前创建的这个表中保留所有跟踪历史......
-
向您的老板介绍解决方案并向他解释使用他的旧方案与使用这个方案的成本/收益如何?使用一些旧表有什么价值?如果您告诉我们 SQL Server 的版本(2000、2005、2008、2012?)也许会有所帮助
-
最初可能是 SQL Server 2000。现在我们是 2012,所以我们可以使用更新的技术。而且他非常不灵活地做出不符合当前工作方式的更改。我花了好几个月才让他在我们当前的系统中允许 AJAX,所以我不认为这是一场我能赢的战斗。此外,我们当前使用的系统都是自制的,在这个历史表中有很多钩子,所以从他的角度来看,重写与更新和维护旧历史表相关的数千行代码的成本与收益并不相同那是有益的。
标签: sql-server stored-procedures