什么是更好的方法来处理这个SQL逻辑?

时间:2009-07-17 15:13:40

标签: sql sql-server-2005

在存储过程内部,我填充了一个项目表(#Items)。只是关于他们的基本信息。但是对于每个项目,我需要确保我可以出售它们,为了做到这一点,我需要执行大量的验证。为了保持存储过程的可维护性,我将逻辑移到另一个存储过程中。

为临时表中的每个项调用存储过程的最佳方法是什么?

我现在拥有它的方式,我应用一个标识列,然后只执行一个while循环,为每一行执行存储过程并将验证结果插入临时表。 (#Validation)

但是现在逻辑已经改变,并且在#Items的创建和循环的执行之间,删除了一些记录,这会破坏while循环,因为Identity不再等于计数器。

我可以通过删除标识列并在while循环之前重新应用它来处理它,但我只是想知道是否有更好的方法。如果我应用order by子句,是否有办法在索引处获取特定行?

我知道我可以做一个光标,但这对我来说是一种痛苦。性能也是一个值得关注的问题,快速的只读游标是否比while循环更好? #Items表中的行数不是很大,最多可能是50行,但是存储过程会被频繁调用。

4 个答案:

答案 0 :(得分:3)

  1. 将验证存储过程转换为用户定义的函数,该函数接受项目ID或验证项目记录所需的数据列
  2. 创建临时表
  3. 插入所有商品
  4. 为在WHERE子句中调用新UDF的临时表编写删除查询。

答案 1 :(得分:2)

我同意如果你能以套装为基础,那么就这样做。也许将验证放入用户定义的函数而不是sproc中以启用它。哪个可能为您能够以集合为基础铺平道路。

e.g。

SELECT * FROM SomeTable WHERE dbo.fnIsValid(dataitem1, dataitem2....) = 1

但是,根据您的具体情况,我知道这可能不可能,所以......

根据现在了解IDENTITY /循环问题进行更正修改: 您可以在SQL 2005中使用ROW_NUMBER()来获取下一行,如果IDENTITY字段中存在间隙则无关紧要,因为这将为您告诉它的每个记录分配一个行号: - 获取下一条记录 SELECT * FROM ( SELECT ROW_NUMBER()OVER(由IDField ASC订购)AS RowNo,* 来自#temptable )s 在哪里.RowNo = @Counter

答案 2 :(得分:1)

这种业务逻辑真的必须在数据库中吗? 我对你的场景了解不多,但也许你最好将你想要用SP建模的决定转移到应用程序中?

因此,您可能尝试使用函数而不是该逻辑的存储过程,并将此函数的结果作为临时表中的列包含在内?这对你有用吗?或者,如果您每次在以后使用时都需要实时数据,那么函数返回0/1值(包含在选择列表中)无论如何都可能是一个不错的选择

答案 3 :(得分:0)

如果可以使用查询重写存储过程逻辑,i。即基于集合的方法?

你应该先试试这个。