0

我的代码确实有效,我不需要帮助。我想知道我所做的是否被认为是可以接受的。

在我正在编写的 T-SQL 脚本的一个特定部分中,我必须运行几乎类似的插入语句大约 20 次。在每种情况下,只有一部分 WHERE 子句不同。想要循环,而不是有 20 个几乎相同的插入,我使用 WHILE 循环来运行一些动态 SQL,并将 WHERE 子句的不同部分存储在数据库中。奇迹般有效。值得注意的是,这种情况下的 INSERT 语句在数量或内容上可能会有所不同,我觉得这个解决方案可以很简单地处理这个问题。

当我向我的一位同事展示这个问题的解决方案时,他的一只眉毛扬了起来,他看着我,好像我长出了一个新脑袋。他建议有更好的方法。可能是这样,而且我是大三学生,我会谦虚地接受它。但是,我确实想问社区这是否看起来很奇怪、不专业或违反一般标准/最佳实践。

如果需要,我可以发布代码,但出于此目的,希望我已经给了你足够的评论一种或另一种方式。

TIA

编辑 -

好的,这里要求的是代码。我不会试图解释它,因为它是一罐蠕虫,但它就是这样。

DECLARE @varOfferId INT = 1
DECLARE @MaxOfferId INT = (SELECT COUNT(DISTINCT offer_id) FROM obp.CellCodes_Offers
DECLARE @SQLWhereClause VARCHAR(1000)
DECLARE @SQLStatement VARCHAR(1000)

WHILE @varOfferId <= @MaxOfferId
BEGIN
SET @SQLWhereClause = (SELECT where_clause FROM obp.Offers WHERE offer_id = @varOfferId)
SET @SQLStatement = 
'INSERT INTO obp.Offers_Contacts ' +
    'SELECT DISTINCT o.contact_id, ' + CONVERT(VARCHAR(2), @varOfferId) +
    ' FROM obp.Onboarding AS o
    WHERE ' + @SQLWhereClause +
    ' AND o2.contact_id = o.contact_id)
      AND ' + CONVERT(VARCHAR(2), @varOfferId) + ' IN(
      SELECT cc.offer_id
      FROM obp.CellCodes_Offers AS cc
      WHERE cc.cellcode = o.cellcode)'

EXECUTE (@SQLStatement)
SET @varOfferId = @varOfferId + 1
END

因此,到目前为止,似乎一致认为这不是一个好主意。好的,我很好。但我不确定我是否同意从维护的角度来看它更容易。现在我的代码查看“优惠”表,获取行数并循环多次。如果他们在未来添加更多报价(或减少报价),我所要做的就是插入(或删除)并在报价中包含适当的 WHERE 子句,我们就在路上。或者,如果我编写所有单独的 INSERTS,如果它们添加或删除,我必须触摸代码,这意味着测试/qa。想法?

但是,我确实同意其他几点,所以我想我明天会回到绘图板上!

4

2 回答 2

2

优点:

  1. 您缩短了代码,节省了一些时间

缺点:

  1. 您现在容易受到SQL 注入的影响
  2. 您的数据库代码现在一半在数据库中,一半在表中 - 这将使维护您的代码的人更难维护。
  3. 调试会很困难。

如果您必须编写 20 条不同的语句,则可以使用与您已经创建的非常相似的 WHILE LOOP 自动生成它们。

例如

SELECT 'insert into mytable (x,y,z) from a join b on a.x = b.x ' + wherecolumn
from wheretable

这将为您提供需要粘贴到存储过程中的代码。您甚至可以将上面的语句保留在存储过程中,注释掉,以便其他人将来可以在列结构发生变化时重新使用它。

对于我见过的关于动态 SQL 的最佳帖子,请查看Erland Somerskog 的页面。

于 2013-10-08T02:51:40.517 回答
0

我认为在数据库中记录差异相对不那么直接,并且以后修改也不方便。我只会写一个脚本来做这件事,然后直接在脚本中写下条件。

例如,在 Python 中,您可能会编写类似这样的内容。

    import MySQLdb
    import MySQLdb.cursors

    field_value_pairs = {'f1':'v1', 'f2':'v2', 'f3':'v3'}  # this is where you could modify to meet your different cases

    db = MySQLdb.connect(host=host_name, user=user_name, passwd=password, \
        unix_socket=socket_info)
    cursor = db.cursor()
    db.select_db(db_name)

    for field in field_value_pairs.keys():
      cursor.execute("""INSERT INTO tbl_name (%s) VALUES (%s)""", field, field_value_pairs[field])
      db.commit()

    cursor.close()
    db.close()
于 2013-10-08T02:33:52.937 回答