SQL 存储过程创建与调用方法

1次阅读

mysql需改分隔符(如delimiter $$)避免分号误解析;postgresql用create or replace function替代存储过程,返回void;sql server参数默认NULL,需用is null判断且注意权限与命名限定。

SQL 存储过程创建与调用方法

MySQL 中 CREATE PROCEDURE 语法写错就报错,关键在分号和分隔符

MySQL 默认用分号 ; 当语句结束符,但存储过程中有多个语句(比如 DECLAREselectif),直接写会提前触发解析,导致语法错误。必须先改分隔符。

  • 创建前加 DELIMITER $$,把结束符临时改成 $$
  • 过程体里所有语句仍用 ;,只在最后用 $$ 结束整个 CREATE PROCEDURE
  • 创建完记得恢复:再写一行 DELIMITER ;,否则后续普通 SQL 会报错

常见错误现象:Error 1064 (42000): You have an error in your SQL syntax —— 基本就是分隔符没切好。

PostgreSQL 用 CREATE OR REPLACE FUNCTION,没有“存储过程”概念

PostgreSQL 不支持标准 SQL 的 CREATE PROCEDURE(直到 v11 才加实验性 PROCEDURE,且需显式调用 CALL)。日常用函数替代,返回 void 就等效于过程。

  • 必须指定 RETURNS void,不能省略
  • 函数体用 BEGIN ... END 包裹,语言用 LANGUAGE plpgsql
  • 调用时用 SELECT my_proc();,不是 CALL(除非你真用了 v11+ 的 CREATE PROCEDURE

示例:CREATE OR REPLACE FUNCTION log_user_login(uid int) RETURNS void AS $$ BEGIN INSERT INTO login_log(user_id) VALUES (uid); END; $$ LANGUAGE plpgsql;

SQL Server 存储过程参数默认是 NULL,不传参容易出空值逻辑

SQL Server 的 CREATE PROCEDURE 允许参数不传,且默认为 NULL,不像 MySQL/PG 那样报错或要求全填。这常导致条件判断失效。

  • 显式写默认值更安全,比如 @status VARCHAR(20) = 'active'
  • IS NULL 判断传参与否,别直接 = NULL(永远为 false)
  • 如果过程里要拼动态 SQL,注意 NULL 参与字符串拼接会让整个结果变 NULL

典型坑:WHERE status = @status@statusNULL 时不匹配任何行——得写成 WHERE (@status IS NULL OR status = @status)

调用时权限不足或跨库引用,EXEC / CALL 会静默失败或报错

不同数据库对调用权限、schema 和库名的处理差异大,不加限定容易找不到对象

  • MySQL 用 CALL db_name.proc_name(),但当前用户必须有该库的 EXECUTE 权限(不是 SELECT
  • SQL Server 推荐用四部分名:EXEC [server].[db].[schema].[proc],省略可能走错默认 schema(比如 dbo vs user1
  • PostgreSQL 调用函数必须带括号,哪怕无参:SELECT my_func();,写成 SELECT my_func; 是查函数 OID,不是执行

最容易被忽略的是:SQL Server 中,如果过程里用了临时表或动态 SQL,而调用者没被授过 VIEW SERVER STATE 或对应库的 UNMASK 权限,可能查不到数据却无提示。

text=ZqhQzanResources