此处显示的我的存储过程有什么问题?

What's wrong with my stored procedure shown here?

我正在尝试编写练习存储过程查询。

DELIMITER $$ 

CREATE PROCEDURE Select_All_Products_Ordered()
BEGIN $$
    SELECT * 
    FROM northwind.Customers
    ORDER BY CompanyName;
END $$

DELIMITER ;

它不识别字符的第一个分隔符、Ordered() 之后的括号、table 名称,也不识别公司名称。

存储过程声明语法

T-SQL(SQL服务器使用的SQL版本)没有用括号声明存储过程参数。相反,它将参数列表放在过程名称和关键字 AS 之间,如下所示:

CREATE PROCEDURE Select_All_Products_Ordered 
    @myparameter int = 5
AS
-- ...

过程不必有任何参数,在这种情况下 AS 只需跟在过程名称之后。因此,代码中的括号应替换为关键字 AS.

分隔符

DELIMITER 未在 T-SQL.

中使用

此关键字用于 MySql(可能还有其他数据库),因为它们无法判断存储过程主体中的 ; 字符是否分隔过程的结尾或结尾过程中的一个语句。所以为了解决这个问题,重新定义了分隔符。

T-SQL 相反,将从 AS 关键字到批处理结束的所有内容解释为存储过程的一部分。因此它不会被 ; 字符混淆,也不需要重新定义定界符。

批处理通常会 运行 文件结尾,但是,大多数 T-SQL 编辑器会将脚本分成多个批处理以发送到服务器。这通常是通过在行首的单词 GO 上拆分脚本来完成的。请注意,执行此操作的是编辑器,而不是 SQL 服务器。如果您不喜欢 GO,SQL Server Management Studio (SSMS) 等编辑器可以在设置中将其配置为不同的模式。 ADO.Net 等库也不会这样做,因此您必须自己拆分脚本并通过单独的服务器调用发送每个批次。

开始和结束

BEGINEND 仅当您希望将一组语句分组到一个块中时才需要。例如,这对于 WHILE 语句很有用。由于 T-SQL 将从 AS 关键字到批处理结束的所有内容都视为存储过程的一部分,因此此处不需要它们。那就是说如果你想离开他们也不会受伤。

缺少架构

table 等对象在 SQL 服务器数据库中分组到模式中。它们各有一个名称,但默认名称是 dbo。您使用了对客户 table 的多部分引用,但是尽管您提供了数据库和 table 名称,但您还没有提供架构名称。要指定模式,请将其放在数据库和服务器名称之间,例如 northwind.dbo.Customers.

可以省略架构名称,SQL 服务器将使用数据库的默认值,但在这种情况下,您需要像这样的两个点 northwind..Customers.

也可以在另一台服务器上引用 table,前提是与另一台服务器的连接已注册到您 运行 所在的服务器。在这种情况下,您将使用由四部分组成的标识符 ServerName.DatabaseName.SchemaName.TableName.

对于服务器应该知道的事情,您可以从一开始就省略一些项目。因此,如果您连接到特定数据库,则可以省略服务器名称和数据库名称。同样如前所述,可以省略架构,并假定登录用户的默认值。

结论

因此,为了使用像 SQL Server Management Studio 这样的客户端工具在 SQL 服务器上获取到 运行 的存储过程,你可以这样写(我已经包含了最后调用过程以显示批次分隔符,但这不是必需的):

CREATE PROCEDURE Select_All_Products_Ordered 
AS
    SELECT * 
    FROM northwind.dbo.Customers
    ORDER BY CompanyName;
GO

EXEC Select_All_Products_Ordered
GO

有关 T-SQL 的存储过程语法的更多详细信息可以在 CREATE PROCEDURE (Transact-SQL).

下的 Microsoft 文档站点上找到