在数据库中存储SQL代码

时间:2013-10-08 02:24:39

标签: sql sql-server tsql

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

在我写的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

因此,迄今为止的共识似乎认为这不是一个好主意。好的,我很擅长。但是我不确定我是否同意从维护的角度来看它更容易。现在我的代码查看'Offers'表,获取行数并循环多次。如果他们在未来添加更多优惠(或减少优惠),我所要做的就是INSERT(或DELETE)并包含带有相应WHERE子句的商品,我们正在路上。或者,如果我写了所有单独的INSERTS,如果他们添加或删除我必须触摸代码,这意味着测试/ qa。想法?

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

2 个答案:

答案 0 :(得分:2)

<强>优点:

  1. 您的代码更短,节省了一些时间
  2. <强>缺点:

    1. 您现在容易受到SQL Injection
    2. 的影响
    3. 您的数据库代码现在是数据库中的一半而表中的一半 - 这将使维护代码的人员的维护更加困难。
    4. 调试很困难。
    5. 如果你必须编写20个不同的语句,可以使用与你已经完成的WHILE LOOP非常相似的WHILE LOOP自动生成它们。

      e.g。

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

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

      对于我在动态SQL上看过的最好的帖子,请查看Erland Somerskog's page here.

答案 1 :(得分: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()