【问题标题】:Sql - goto statementSql - goto 语句
【发布时间】:2010-06-15 14:16:57
【问题描述】:

在 SQL 查询中使用“goto”语句是一种好习惯吗?

【问题讨论】:

  • @ircmaxell 我的观点完全正确。
  • SQL 中没有 GOTO - 只有 T-SQL

标签: sql-server tsql goto


【解决方案1】:

取决于 SQL - 一些方言不提供除 GOTO 之外的有用的流控制机制。

GOTO 通常是不好的形式。

【讨论】:

    【解决方案2】:

    不在生产代码中但用于测试可能没问题。

    例如,想要为存储过程提供回归测试,其中“公共位”是对正在测试的过程和调试语句的调用。

    declare @test int;
    set @test = 1;
    goto tests
    
    common:
    print 'common bit'
    
    tests:
    if @test = 1 print '1';
    if @test = 2 print '2';
    if @test = 3 print '3';
    
    set @test = @test + 1;
    if @test <= 3 goto common
    print 'finished ' + cast(@test as varchar(5))
    go  -- goto can not be used past go!
    

    作为一个 t-sql 菜鸟,我希望在范围内声明过程或函数以执行“通用位”,但这是我经过多次谷歌搜索后能想到的最好的方法。为什么必须为要重用的每一位代码设置一个存储过程。特别是对于非生产性工作。

    【讨论】:

    • 您对使用 GOTO 使用少量功能提出了很好的观点。 :-) 我们需要 T-SQL 中的 Lambda 表达式! ;-)
    【解决方案3】:

    没有。

    与其他语言一样,几乎总是有比 Goto 更好的选择。

    如果您告诉我们您正在使用哪个 SQL 包以及您想要完成什么,我们或许可以为您提供一个确切的想法。

    【讨论】:

    • 是别人写的存储过程。
    • @BhejaFry - 但它是 T-SQL、PL-SQL、MySQL 等吗?
    • 是T-SQL,pl-sql不支持goto吗?
    【解决方案4】:

    我的猜测是否定的。我对任何现代语言中的 goto 语句的一般规则是,如果您使用它们,那么您的设计就有问题。

    【讨论】:

      【解决方案5】:

      goto 是具有自身特点的关键字。 当需要直接跳转到某个级别时,我们可以使用 goto。

      让我们举个例子... 在我的存储过程中,我需要处理 4 个临时表中的数据。 在临时表中插入记录后的每个级别,我需要检查该临时临时表中是否存在记录,如果没有插入记录,那么我可以使用 goto 直接跳下,而不是进一步处理。 label 是我们应该跳转的点:

       CREATE TABLE #tmpMsNos (custPo CHAR(24))
      
          CREATE TABLE #tmpValidBilltos (billto CHAR(12))
      
          CREATE TABLE #tmpOrders (
              fh_pkey INT
              ,fh_id CHAR(8)
              ,custPo CHAR(24)
              ,lastchOfCustInsert DATETIME
              )
      
          CREATE TABLE #tmpOrdersFiltered (
              fh_pkey INT
              ,fh_id CHAR(8)
              ,custPo CHAR(24)
              ,lastchOfCustInsert DATETIME
              ,onbDate DATETIME
              ,rapDate DATETIME
              )
      
          CREATE TABLE #tmpLoad (
              custPo CHAR(24)
              ,ld_pkey INT
              ,ld_wkpmpn CHAR(25)
              ,lda_barcode VARCHAR(30)
              ,ld_createdOn DATETIME
              ,ReceivedDate DATETIME
              ,DispatchedDate DATETIME
              )
      
      INSERT INTO #tmpMsNos
          SELECT cast(itemValue AS CHAR(24)) 
          FROM dbo.fn_array_to_table(@pMsNos, ',')
      
      IF (
                  NOT EXISTS (
                      SELECT 1
                      FROM #tmpMsNos
                      )
                  )
          BEGIN
              GOTO label
          END
      INSERT INTO #tmpValidBilltos
          SELECT CONVERT(CHAR(12), xm_doref)
          FROM xmlref x
          WHERE xm_element = 'THD-BoxtruckRequest'
              AND xm_attribute = 'THD-BoxtruckBillto'
      
      IF (
                  NOT EXISTS (
                      SELECT 1
                      FROM #tmpValidBilltos
                      )
                  )
          BEGIN
              GOTO label
          END
      
      INSERT INTO #tmpOrders
          SELECT fh.fh_pkey
              ,fh.fh_id
              ,fh.fh_custPo
              ,max(coc.ch_dt)
          FROM #tmpMsNos msNos
          INNER JOIN fcfgthd fh ON msNos.custPo = fh.fh_custPo
          INNER JOIN #tmpValidBilltos bt ON bt.billto = fh.fh_bt_id
          LEFT JOIN chofcust coc ON coc.ch_fhpkey = fh.fh_pkey
          WHERE fh.fh_statcode NOT IN (
                  98 --CAN
                  ,99 --DEL
                  )
              AND fh.fh_ship_dt > @startDate
          GROUP BY fh.fh_pkey
              ,fh.fh_id
              ,fh.fh_custPo
      
          IF (
                  NOT EXISTS (
                      SELECT 1
                      FROM #tmpOrders
                      )
                  )
          BEGIN
              GOTO label
          END
      
      INSERT INTO #tmpOrdersFiltered
          SELECT t.fh_pkey
              ,t.fh_id
              ,t.custPo
              ,t.lastchOfCustInsert
              ,MAX(cocONB.ch_dt)
              ,MAX(cocRAP.ch_dt)
          FROM (
              SELECT tmpO.fh_pkey
                  ,tmpo.fh_id
                  ,tmpO.custPo
                  ,tmpO.lastchOfCustInsert
              FROM #tmpOrders tmpO
              INNER JOIN (
                  SELECT custpo
                      ,max(lastchOfCustInsert) AS MaxInserteddate
                  FROM #tmpOrders
                  GROUP BY custpo
                  ) tmpOgrouped ON tmpO.custpo = tmpOgrouped.custpo
                  AND tmpO.lastchOfCustInsert = tmpOgrouped.MaxInserteddate
              ) AS t
          LEFT JOIN chofcust cocRAP ON cocRAP.ch_fhpkey = t.fh_pkey
              AND cocRAP.ch_stat = 2 -- RAP --TODO: Add comment with status code like 98, 99 -- CAN, DEL for readability - Paresh
          LEFT JOIN chofcust cocONB ON cocONB.ch_fhpkey = t.fh_pkey
              AND cocONB.ch_stat = 5 -- ONB --TODO: Add comment with status code like 98, 99 -- CAN, DEL for readability - Paresh
          GROUP BY t.fh_pkey
              ,t.fh_id
              ,t.custPo
              ,t.lastchOfCustInsert
      
          --TODO: Take an exit if no order found into #tmpOrdersFiltered table, while taking a early exit make sure it doesn't break the calling code (C#)  - Paresh
          IF (
                  NOT EXISTS (
                      SELECT 1
                      FROM #tmpOrdersFiltered
                      )
                  )
          BEGIN
              GOTO label
          END
      INSERT INTO #tmpLoad
          SELECT o.custPo
              ,l.ld_pkey
              ,l.ld_wkpmpn
              ,la.lda_barcode
              ,max(coc.ch_dt)
              ,CASE ISNULL(w.xl_date, '')
                  WHEN ''
                      THEN o.rapDate
                  ELSE w.xl_date
                  END AS ReceivedDate
              ,CASE ISNULL(mm.me_ecpkey, '')
                  WHEN ''
                      THEN o.ONBDate
                  ELSE NULL
                  END AS DispatchedDate
          FROM #tmpOrdersFiltered o
          INNER JOIN fcload l ON l.ld_fhpkey = o.fh_pkey
          LEFT JOIN loadanc la ON la.lda_ldpkey = l.ld_pkey
          LEFT JOIN wkxaclog w ON w.xl_ldpkey = l.ld_pkey
          LEFT JOIN multiexceps mm ON mm.me_ldpkey = l.ld_pkey
              AND mm.me_ecpkey = @missingitemexcep
          LEFT JOIN chofcust COC ON coc.ch_ldpkey = l.ld_pkey
              AND coc.ch_stat = 64 -- 64= ILH
          GROUP BY o.custPo
              ,l.ld_pkey
              ,l.ld_wkpmpn
              ,la.lda_barcode
              ,w.xl_date
              ,o.rapDate
              ,mm.me_ecpkey
              ,o.ONBDate
      

      【讨论】:

        猜你喜欢
        • 2021-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        相关资源
        最近更新 更多