Tsql 关于构造T-SQL的几个问题

Tsql 关于构造T-SQL的几个问题,tsql,Tsql,我正在学习T-SQL,并试图了解如何处理it/最佳实践。通过一些例子,我有三个问题: 1) 来自Python,是否有一个公认的样式指南(类似于PEP8)或方法来设计T-SQL,还是更像JavaScript 2) 在创建存储过程和函数时,我看到一些作者总是使用主开始/结束块,而其他人则不使用。起初,我认为如果你有多条语句,就需要开始/结束。然而,这似乎不是真的,因为我看到了没有主开始/结束的冗长存储过程。有什么想法吗 3) 在存储过程中,一些作者似乎喜欢将部分代码包含在开始/结束块中。我不明白你为

我正在学习T-SQL,并试图了解如何处理it/最佳实践。通过一些例子,我有三个问题:

1) 来自Python,是否有一个公认的样式指南(类似于PEP8)或方法来设计T-SQL,还是更像JavaScript

2) 在创建存储过程和函数时,我看到一些作者总是使用主开始/结束块,而其他人则不使用。起初,我认为如果你有多条语句,就需要开始/结束。然而,这似乎不是真的,因为我看到了没有主开始/结束的冗长存储过程。有什么想法吗

3) 在存储过程中,一些作者似乎喜欢将部分代码包含在开始/结束块中。我不明白你为什么要这么做,不知道我是否遗漏了什么。例如:

CREATE PROCEDURE <NAME> (
  <Parameter List...>
)
AS
BEGIN
    -- Setup:
    -- Declare/initialize variables...

    BEGIN TRY
        BEGIN TRANSACTION

        -- Validity check 1:
        IF @Param1 ...
        BEGIN
            -- Do stuff...
        END

        -- Validity check 2
        IF @Param2 ...
        BEGIN
            -- Do stuff...
        END
        -- Update - added BEGIN/END after if blocks for clarity

        -- Why wrap these statements in a BEGIN/END Block???
        BEGIN
            --Add the entry
            INSERT dbo.JournalClientFamilyChanges (
                    HouseholdMembersID,
                    PreviousClientsID,
                    NewClientsID,
                    ActionTaken,
                    Notes,
                    ModifiedBy,
                    ModifiedDate
                )
            VALUES (
                    @HouseholdMembersID,
                    @PreviousClientsID,
                    @NewClientsID,
                    @ActionTaken,
                    @Notes,
                    @ModifiedBy,
                    SYSDATETIME()
                )

            SET @success =1;
            SET @ErrorStatus ='';
            COMMIT TRANSACTION;
        END
    END TRY

    BEGIN CATCH
        -- Error handling...
    END CATCH
END
创建过程(
)
作为
开始
--设置:
--声明/初始化变量。。。
开始尝试
开始交易
--有效性检查1:
如果@Param1。。。
开始
--做些事情。。。
结束
--有效性检查2
如果@Param2。。。
开始
--做些事情。。。
结束
--更新-为清晰起见,在if块后添加开始/结束
--为什么要将这些语句包装在开始/结束块中???
开始
--添加条目
插入dbo.JournalClientFamilyChanges(
户主席德,
以前的客户sid,
新客户席德,
采取的行动,
笔记,
由,
修饰酸
)
价值观(
@户主席德,
@以前的客户sid,
@新客户席德,
@采取的行动,
@注意,
@由,
SYSDATETIME()
)
设置@success=1;
设置@ErrorStatus='';
提交事务;
结束
结束尝试
开始捕捉
--错误处理。。。
端接
结束
任何想法都值得赞赏


--Jim以你自己的例子回答你的问题

    IF @Param1 ...

    -- Validity check 2
    IF @Param2 ...

    -- Why wrap these statements in a BEGIN/END Block???
    BEGIN
        --Add the entry
        INSERT dbo.JournalClientFamilyChanges (
                HouseholdMembersID,
                ...
            )
        VALUES (
                @HouseholdMembersID,
                @PreviousClientsID,
                ... 
            )

        SET @success =1;
        SET @ErrorStatus ='';
        COMMIT TRANSACTION;
    END
有一个
IF
,它会在特定情况下调用下面的代码。如果没有
开始。。。结束
这仅对下一条语句有效。使用
开始。。。END
将看到
IF
条件所覆盖的整个代码块(带有
SET
COMMIT
的行)

试试这个:

DECLARE @SomeInt INT=0;

IF @SomeInt=1
PRINT 'Example 1: hello, this is the first line';
PRINT 'Example 1: hello, the next line';

IF @SomeInt=1
BEGIN
PRINT 'Example 2: hello, this is the first line';
PRINT 'Example 2: hello, the next line';
END
为了更好的可读性,可以使用缩进。但这与发动机无关。有一些语言使用缩进作为块标记,其他语言使用偏旁或任何类型的括号。T-SQL使用
BEGIN。。。结束
。有时,人们在更大的过程中使用它只是为了允许折叠(如C中的
#区域

更新 只是为了反映下面的评论:OP在某种程度上改变了最初的问题,
开始。。。如果
,则结束不再连接到
。所以问题应该是:为什么要使用
开始。。。结束
无任何功能原因

答案是

  • 将某些代码行标记为“块”
  • 。。。因此强调了功能单元
  • 崩溃是一个很好的副作用

BEGIN
..
END
表示T-SQL中的代码块,很像c#中的
{…}
或python中的缩进。@ZoharPeled我就是这么想的。然而,当我看到人们如何在T-SQL中使用BEGIN…END时,它与非SQL语言中的代码块并不匹配。在C++或Python中,使用块有非常特殊的原因——如果需要多个语句,则需要它,否则就不需要。然而,我正在阅读的许多T-SQL代码并不遵循这些规则。所以我的问题是,为什么?在T-SQL中,即使不需要代码块,也可以添加代码块。我曾经有一个项目使用了很长的存储过程,我使用
begin…end
将它们分成了几个部分,以便能够在SSMS中折叠它们,只看到相关的代码。TSQL还包含许多可选语法—例如—您可以编写
insert-into-table(col1,col2)值(val1,val2)
,但您也可以编写
insert-table-values(val1,val2)
—如果表中只包含两列,则两列的工作方式相同(尽管始终包含列名是最佳实践).Ahhh-能够在SSMS中折叠代码是有意义的。谢谢谢谢你的回答。很抱歉,我的例子不清楚。如果使用/不使用积木,我熟悉IF的工作原理。我更新了我的示例,以表明这不是我想要的。不过,它可能很简单,就像使用BEGIN…END允许在编辑器中按您的建议折叠代码一样。@JamesS。好的,那个编辑过的样本现在是另一回事了…:-)没问题。。。使用
开始。。。END
是一种很好的方法,可以将一些代码行标记为“块”,从而强调功能单元。。。崩溃是一个很好的副作用…@JamesS。你的改变使我的答案无效。。。你可能需要阅读我的更新。。。
IF @SomeInt=1
    PRINT 'Example 1: hello, this is the first line';

PRINT 'Example 1: hello, the next line';

IF @SomeInt=1
BEGIN
    PRINT 'Example 2: hello, this is the first line';
    PRINT 'Example 2: hello, the next line';
END