Sql - Перейти к заявлению - PullRequest
11 голосов
/ 15 июня 2010

Является ли хорошей практикой использование операторов goto в запросах SQL?

Ответы [ 5 ]

9 голосов
/ 15 июня 2010

Зависит от SQL - некоторые из диалектов не предоставляют полезного механизма управления потоком, кроме GOTO.

GOTO, как правило, плохая форма.

6 голосов
/ 15 ноября 2011

Не в рабочем коде, но для тестирования может быть в порядке.

Например, желая обеспечить регрессионное тестирование для хранимой процедуры, где «общий бит» - это вызов тестируемой процедуры и операторы отладки.

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, я надеялся, что процедура или функция объявляются в области видимости для выполнения "общего бита", но это было лучшее, что я мог придумать после долгих поисков.Зачем вам нужно настраивать хранимую процедуру для каждого бита кода, который вы хотите использовать повторно.Специально для непроизводственных работ.

3 голосов
/ 15 июня 2010

номер

Как и в других языках, почти всегда есть лучший вариант использования, чем в Goto.

Если вы сообщите нам, какой пакет SQL вы используете и чего пытаетесь достичь, мы сможем дать вам представление о том, что именно может подойти.

0 голосов
/ 10 марта 2017

goto - это ключевое слово со своей функцией. Мы можем использовать goto всякий раз, когда требуется перейти прямо на какой-то уровень.

Давайте возьмем пример ... В моей хранимой процедуре мне нужно работать с данными в 4 временных таблицах. на каждом уровне после вставки записей в временную таблицу мне нужно проверить, присутствуют ли записи в этой временной температуре или нет, если записи не были вставлены, поэтому вместо дальнейшей обработки я могу напрямую перейти с помощью goto. метка - это точка, куда мы должны перейти:

 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
0 голосов
/ 15 июня 2010

Я думаю, что нет. Мое общее правило для операторов goto на любом современном языке: если вы используете их, что-то не так с вашим дизайном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...