JetBrains Rider 2025.2 Help

SQL 中的代码检查

本主题列出了 SQL 中所有可用的 JetBrains Rider 代码检查

您可以在 编辑器 | 检查设置 | 检查严重性 | 其他语言 设置页面  Ctrl+Alt+S 上切换特定检查或更改其严重性级别。

检查

描述

默认严重性

添加无默认值的非空列

报告尝试创建没有默认值的 NOT NULL 列。

示例(Microsoft SQL Server):

CREATE TABLE foo (a INT, b INT) ALTER TABLE foo ADD c INT NOT NULL;

默认情况下,列可以包含 NULL 值。 在示例中,我们使用了 NOT NULL 约束,强制列不接受 NULL 值。 如果我们禁止使用 NULL 值,则必须设置 SQL 在创建新记录时可以使用的默认值。

ALTER TABLE foo ADD c INT NOT NULL DEFAULT 42;

您可以通过使用“添加默认值”快速修复功能快速添加默认值。

警告 警告

与聚合相关的问题

报告 SQL 聚合函数的无效用法。

考虑以下情况:

  • 在 HAVING 和 ORDER BY 子句中使用的列未包含在 GROUP BY 子句中。

    CREATE TABLE foo(id INT PRIMARY KEY, a INT, b INT); SELECT a, MAX(b) FROM foo GROUP BY a HAVING b > 0; SELECT * FROM foo GROUP BY a ORDER BY b;

    当按主键分组时,此规则不适用。

    SELECT * FROM foo GROUP BY id ORDER BY b;
  • 错误上下文中的聚合函数。 通常,您可以在以下上下文中使用聚合函数:SELECT 中的表达式列表;HAVING 和 ORDER BY 部分;以及其他特定方言的情况。 以下查询将显示错误。

    SELECT a FROM foo WHERE MAX(b) > 0; SELECT a FROM foo GROUP BY MAX(a);
  • 嵌套调用聚合函数。

    SELECT MAX(SUM(a)) FROM foo GROUP BY a;

    此规则不适用于分析函数。 以下查询是有效且正确的。

    SELECT MAX(SUM(a) OVER ()) FROM foo;
  • 在没有聚合函数的情况下使用 HAVING。 在这种情况下,请考虑使用 WHERE 部分重写代码。

    SELECT a, MAX(b) FROM foo GROUP BY a HAVING a > 0;

警告 警告

模糊引用

报告具有相同名称但属于不同表的列。

示例(MySQL):

CREATE TABLE foo(id INT PRIMARY KEY); CREATE TABLE bar(id INT PRIMARY KEY); SELECT foo.id, bar.id FROM foo, bar WHERE id > 0;

iD 列出现在 foo条形图 表中。 您需要限定列名以使查询正确。

SELECT foo.id, bar.id FROM foo, bar WHERE foo.id > 0;

警告 警告

自动递增重复

报告包含两个具有自动递增的列的表。 在 MySQL、Microsoft SQL Server 和 Db2 方言中,一个表只能有一个具有自动递增选项的字段,并且该字段必须是键。

示例(MySQL):

CREATE TABLE my_table ( id INT AUTO_INCREMENT, c2 INT AUTO_INCREMENT, );

c2 的 AUTO_INCREMENT 约束将被高亮显示,因为 c1 已经具有此约束。 要修复此警告,您可以将 iD 设置为主键,并删除 c2 的 AUTO_INCREMENT。

CREATE TABLE my_table ( id INT AUTO_INCREMENT PRIMARY KEY, c2 INT, );

警告 警告

检查 USING 子句中的列

报告 USING 子句中不存在于两个表中的列。

示例(MySQL):

CREATE TABLE t1 (i INT, j INT); CREATE TABLE t2 (k INT, l INT); SELECT * FROM t1 JOIN t2 USING (j);

在 USING 子句中,列名必须同时存在于两个表中,SELECT 查询将自动使用给定的列名连接这些表。 由于我们在 jt2 中没有该列,因此我们可以使用 ON 重写查询。 ON 子句可以连接两个表,即使列名在两个表中不匹配。

SELECT * FROM t1 JOIN t2 ON t1.j = t2.l;

警告 警告

列被别名遮蔽

报告 SELECT 别名与 FROM 子句中的列名相匹配的情况。

示例(MySQL):

CREATE TABLE foo (a INT, b INT, c INT); SELECT a b, c FROM foo;

a 列使用了 b 别名,但 b 名称也被 foo 表中的列使用。

警告 警告

列应在 GROUP BY 子句中

报告未在 GROUP BY 子句中或未在聚合函数调用中的列。

示例(Microsoft SQL Server):

CREATE TABLE t1 (a INT, b INT); SELECT a, b FROM t1 GROUP BY a;

如果您运行 SELECT 查询,您将收到错误,因为 Microsoft SQL Server 期望 b 列在 GROUP BY 中或在聚合函数中使用。 以下两个示例将修复该错误。

SELECT a, b FROM t1 GROUP BY a, b; SELECT a, max(b) max_b FROM t1 GROUP BY a;

警告 警告

恒定条件

报告 WHERE 或 JOIN 子句中始终为 TRUE 或始终为 FALSE 的条件。

示例(MySQL):

CREATE TABLE t1 (a TEXT, b INT, c BOOLEAN); SELECT a FROM t1 WHERE 'Cat' = 'Cat';

'Cat' = 'Cat' 始终为 true,将被报告。

警告 警告

恒定表达式

报告始终为 true、false 或 null 的条件和表达式。

示例(MySQL):

CREATE TABLE t1 (a TEXT, b INT, c BOOLEAN); SELECT a FROM t1 WHERE 'Cat' = 'Cat'; SELECT a FROM t1 WHERE 'Cat' = null;

'Cat' = 'Cat' 始终为 true,将被报告。

'Cat' = null 始终为 null,将被报告。

警告 警告

当前控制台模式已内省

报告当前会话中未内省的模式和数据库。

例如,当您尝试在未内省的模式中创建表时,可能会出现此警告。

内省是一种检查数据源的方法。 当您执行内省时,会检查数据源中的结构信息,以检测表、列、函数及其属性等元素。

警告 警告

没有 WHERE 子句的删除或更新语句

报告没有 WHERE 子句的 DELETE 或 UPDATE 语句的用法。

没有 WHERE 子句,DELETE 会删除表中的所有数据,而 UPDATE 会覆盖表中所有行的值。

示例(MySQL):

CREATE TABLE t1 (a TEXT, b INT, c BOOLEAN); update t1 set a = 'Smith'; delete from t1;

警告 警告

已弃用的类型

报告已弃用并可能在未来版本的 DBMS 中消失的类型的用法。

报告的类型:

示例(Oracle):

CREATE TABLE ot.foo( a NUMBER GENERATED BY DEFAULT AS IDENTITY, b LONG NOT NULL );

警告 警告

在 SELECT 中重复的列名

报告 SELECT 列表中列别名的重复名称。

示例(Sybase ASE):

CREATE TABLE t1 (a TEXT, b INT, c INT); SELECT a AS x, b AS x FROM t1;

x 别名名称用于 ab 列。 这些分配被高亮显示为错误,因为在 Sybase ASE 中不能为列使用相同的别名名称。

警告 警告

每个派生表都应有别名

报告没有别名的派生表。

示例(MySQL):

CREATE TABLE table1 (id INT, name VARCHAR(20), cats FLOAT); CREATE TABLE table2 (id INT, age INTEGER); SELECT id AS ID, name, cats, age FROM (SELECT table1.id, name, cats, age FROM table1 JOIN table2 ON table1.id = table2.id);

根据 Derived Tables at dev.mysql.com ,别名是强制性的。 您可以通过使用“引入别名”快速修复功能添加别名。

应用快速修复后:

SELECT id AS ID, name, cats, age FROM (SELECT table1.id, name, cats, age FROM table1 JOIN table2 ON table1.id = table2.id);

警告 警告

函数签名

报告内置函数的签名问题。

检查将报告参数数量错误、无效关键字、错误的数据类型以及其他问题。

示例(MySQL):

CREATE TABLE foo (a INT, b INT, c INT) SELECT IFNULL() FROM foo; -- error SELECT IFNULL(a) FROM foo; -- error SELECT IFNULL(a, b) FROM foo; -- OK SELECT IFNULL(a, b, c) FROM foo; -- error

在 MySQL 中, IFNULL() 函数严格接受两个参数。 因此,只有 SELECT IFNULL(a, b) FROM foo; 查询是正确的。

警告 警告

标识符应加引号

报告在查询中使用 SQL 保留关键字作为标识符名称的情况。

示例(Microsoft SQL Server):

CREATE TABLE select (identity INT IDENTITY NOT NULL, order INT NOT NULL);

我们使用 选择身份验证订单 作为表和列名。 但它们也是 Microsoft SQL Server 中的保留关键字。 因此,为了在查询中将它们用作对象名称,您必须为这些标识符加引号。 要为它们加引号,您可以使用“引用标识符”快速修复功能。

应用快速修复后:

CREATE TABLE [select] ([identity] INT IDENTITY NOT NULL, [order] INT NOT NULL);

警告 警告

格式错误的日期/时间字面量

报告日期和时间字面量中的错误。 此检查在 MySQL、Oracle、Db2 和 H2 中可用。

示例(MySQL):

SELECT TIME '10 -12:13:14' FROM dual; SELECT TIME ' 12 : 13 : 14 ' FROM dual; SELECT TIME '12 13 14' FROM dual; SELECT TIME '12-13-14' FROM dual; SELECT TIME '12.13.14' FROM dual; SELECT TIME '12:13:' FROM dual; SELECT TIME '12:13' FROM dual; SELECT TIME '12:' FROM dual;

在此示例中,日期忽略了 MySQL 对日期和时间字面量的标准。 因此,它们将被高亮显示。 有关 MySQL 中日期和时间字面量的更多信息,请参阅 Date and Time Literals at dev.mysql.com

以下日期和类型字面量对 MySQL 是有效的。

SELECT TIME '12:13:14' FROM dual; SELECT TIME '12:13:14.555' FROM dual; SELECT TIME '12:13:14.' FROM dual; SELECT TIME '-12:13:14' FROM dual; SELECT TIME '10 12:13:14' FROM dual; SELECT TIME '-10 12:13:14' FROM dual;

警告 警告

非法游标状态

报告 SQL 例程中非法的游标状态。

  • 例程包含 CLOSE 或 FETCH 语句,但游标可能已关闭。

  • 例程包含 OPEN 语句,但游标可能已打开。

示例(Microsoft SQL Server):

CREATE TABLE t(col INT); CREATE PROCEDURE foo() AS BEGIN DECLARE my_cursor CURSOR FOR SELECT * FROM t; DECLARE a INT; FETCH my_cursor INTO a; CLOSE my_cursor; END;

根据 CLOSE (Transact-SQL) at docs.microsoft.com ,CLOSE 必须在打开的游标上执行,且不允许在仅声明或已关闭的游标上执行 CLOSE。 因此,我们需要打开游标以修复此警告。

CREATE PROCEDURE foo() AS BEGIN DECLARE my_cursor CURSOR FOR SELECT * FROM t; DECLARE a INT; OPEN my_cursor; FETCH my_cursor INTO a; CLOSE my_cursor; END;

警告 警告

隐式字符串截断

报告超出定义字符长度的变量。

示例(Microsoft SQL Server):

CREATE PROCEDURE test() AS BEGIN DECLARE myVarOk VARCHAR(5) = 'abcde'; DECLARE myVarExceeded VARCHAR(5) = 'abcde12345'; SET myVarOk = 'xyz'; SET myVarExceeded = '123456789'; END;

myVarExceeded 变量定义为 VARCHAR(5) ,但分配的值('abcde12345''123456789' )均超出此限制。 您可以截断分配的值或增加定义的长度。 要增加长度,请使用“增加类型长度”快速修复功能。

应用快速修复后:

CREATE PROCEDURE test() AS BEGIN DECLARE myVarOk VARCHAR(5) = 'abcde'; DECLARE myVarExceeded VARCHAR(10) = 'abcde12345'; SET myVarOk = 'xyz'; SET myVarExceeded = '123456789'; END;

警告 警告

索引依赖于列

报告尝试从索引表中删除列的情况。 此检查在 Microsoft SQL Server 和 Sybase ASE 中可用。

示例(Microsoft SQL Server):

CREATE TABLE test_index ( col INT NOT NULL, col2 INT NOT NULL, col3 INT NOT NULL UNIQUE, col4 VARCHAR(200) ); CREATE UNIQUE INDEX aaaa ON test_index (col, col2); ALTER TABLE test_index DROP COLUMN col;

您无法删除 列,因为它位于索引表中。 要删除该列,您需要先删除 aaaa 索引(例如,DROP INDEX aaaa)。

警告 警告

向 NOT NULL 列插入 NULL

报告将 NULL 值插入仅接受 NOT NULL 值的列的情况。

示例(Microsoft SQL Server):

CREATE TABLE br2 ( id INT NOT NULL, col1 NVARCHAR (20) NOT NULL, col2 NVARCHAR (20) NOT NULL, ); -- INSERT INTO br2 (id, col1, col2) VALUES (1, NULL, NULL);

您不能在 col1col2 中插入 NULL 值,因为它们被定义为 NOT NULL。 如果您按原样运行脚本,您将收到错误。 要修复此代码,请将 VALUES 部分中的 NULL 替换为某些值(例如, 42'bird')。

INSERT INTO br2 (id, col1, col2) VALUES (1, 42, 'bird');

警告 警告

插入生成列

报告将值分配给生成列的 INSERT 语句。 生成列可以读取,但其值不能直接写入。

示例(PostgreSQL):

CREATE TABLE foo ( col1 INT, col2 INT GENERATED ALWAYS AS (col1 + 1) STORED ); INSERT INTO foo(col1, col2) VALUES (1, 2);

您不能将 2 插入到 col2 列中,因为该列是生成的。 要使此脚本正常工作,您可以将 2 更改为 DEFAULT。

INSERT INTO foo(col1, col2) VALUES (1, DEFAULT);

警告 警告

误导性引用

报告 SQL 代码中的模糊引用。

例如,当一个名称同时引用表列和例程参数时。 此类代码的执行可能会由于不直观的解析逻辑导致错误或意外结果。 通常,具有更局部范围的名称优先级更高。

示例(PostgreSQL):

CREATE TABLE foo ( id INT, name VARCHAR(5) ); CREATE FUNCTION func(name VARCHAR(5)) RETURNS INT AS $$ DECLARE b INT; BEGIN -- `name` is ambiguous as it is used as a column name and a parameter SELECT COUNT(*) INTO b FROM foo t WHERE t.name = name; RETURN b; END; $$ LANGUAGE plpgsql;

在 PostgreSQL 中,您可以使用 #variable_conflict 指令显式指定正确的引用。 例如,使用 #variable_conflict use_column 引用列名,或使用 #variable_conflict use_variable 引用参数。

CREATE TABLE foo ( id INT, name VARCHAR(5) ); CREATE FUNCTION func(name VARCHAR(5)) RETURNS INT AS $$ #variable_conflict use_column DECLARE b INT; BEGIN SELECT COUNT(*) INTO b FROM foo t WHERE t.name = name; RETURN b; END; $$ LANGUAGE plpgsql;

警告 警告

缺少列别名

报告输出表达式(例如 SELECT 语句)中没有显式别名的查询。

示例(PostgreSQL):

CREATE TABLE foo(a INT, b INT); SELECT 1, a + 1 AS A2, MAX(b) AS M FROM foo;

已禁用

缺少返回语句

报告没有 RETURN 语句的函数。

示例(Oracle):

CREATE FUNCTION foo RETURN int AS BEGIN END;

foo 函数必须返回整数值,但函数体未返回任何内容。 要修复此错误,请添加 RETURN 语句(例如, return 1;)。

CREATE FUNCTION foo RETURN int AS BEGIN RETURN 1; END;

错误 错误

查询中的多行限制/偏移子句

报告单个查询中使用多个行限制子句的情况。

示例(Microsoft SQL Server):

create table foo(a int); select top 1 * from foo order by a offset 10 rows fetch next 20 rows only;

SELECT TOP 子句用于指定仅返回 1 条记录。 FETCH 子句指定在处理 OFFSET 子句后要返回的行数。 但由于我们已经有了 SELECT TOP 限制子句,FETCH 子句可能是多余的。

警告 警告

应使用命名参数

报告在例程调用中未使用名称的参数。 默认情况下,此检查被禁用。

有关命名参数和未命名参数之间差异的更多信息,请参阅 Binding Parameters by Name (Named Parameters) at docs.microsoft.com

示例(Microsoft SQL Server):

CREATE FUNCTION foo(n INT, m INT) RETURNS INT AS BEGIN RETURN n + m; END; CREATE PROCEDURE test AS BEGIN foo n = 1, m = 2; --- The following call misses parameter names and will be highlighted foo 1, 2; END;

1, 2 参数在 foo 1, 2; 调用中被高亮显示,因为它们缺少名称。

已禁用

未配置数据源

报告数据库工具窗口(视图 | 工具窗口 | 数据库)中缺少数据源的情况。

警告 警告

NULL 比较

报告可以替换为 IS NULL 或 IS NOT NULL 运算符的 NULL 比较。

示例(Microsoft SQL Server):

CREATE TABLE foo ( id int ); SELECT * FROM foo WHERE NULL = NULL; SELECT * FROM foo WHERE NULL != NULL;

NULL = NULL 可以替换为 IS NULLNULL != NULL 比较可以替换为 IS NOT NULL。 要进行此替换,您可以使用“使用 IS NULL 运算符”或“使用 IS NOT NULL 运算符”快速修复功能。

SELECT * FROM foo WHERE NULL IS NULL; SELECT * FROM foo WHERE NULL IS NOT NULL;

警告 警告

多余的 ELSE NULL 子句

报告多余的 ELSE NULL 子句。

示例(MySQL):

SELECT CASE WHEN 2 > 1 THEN 'OK' ELSE NULL END AS alias FROM foo;

ELSE NULL 部分将永远不会被执行,可以省略。

警告 警告

多余的别名表达式

报告重复表中列名称的别名表达式,这些表达式可能是多余的。

示例(PostgreSQL):

CREATE TABLE foo(a INT, b INT); SELECT * FROM foo foo(a, b); SELECT * FROM foo foo(a); SELECT * FROM foo foo(x); SELECT * FROM foo foo(x, y);

前两个别名使用了与 foo 表中相同的列名。 它们被认为是多余的,因为列名是相同的。

警告 警告

COALESCE 调用中的多余代码

报告 COALESCE 函数中除第一个表达式外的所有不为 NULL 的参数。

示例(MySQL):

SELECT COALESCE(NULL, NULL, NULL, 42, NULL, 'string') as a;

第一个 NOT NULL 参数是 42 ,所有其他参数将被灰显。

警告 警告

多余的排序方向

报告 ORDER BY 子句中多余的排序方向,如 ASC 和 DESC。

示例(MySQL):

CREATE TABLE foo(a INT, b INT, c INT); SELECT * FROM foo ORDER BY a ASC, b DESC, c ASC;

ORDER BY 关键字默认按升序排序记录。 因此, ASC 关键字对于 ac 列是多余的。

警告 警告

查询中的多余行限制

报告查询中多余的行限制子句,如 FETCH 和 LIMIT。

示例(PostgreSQL):

CREATE TABLE foo(a INT); SELECT * FROM foo WHERE EXISTS(SELECT * FROM foo LIMIT 2); SELECT * FROM foo WHERE EXISTS(SELECT * FROM foo FETCH FIRST 2 ROWS ONLY);

要修复此警告,您可以向限制子句添加 OFFSET。 如果缺少 OFFSET,则 LIMIT 是多余的,因为 LIMIT 的使用不会影响 EXISTS 的操作结果。 在有 OFFSET 的情况下,我们跳过前 N 行,这将影响输出。

SELECT * FROM foo WHERE EXISTS(SELECT * FROM foo OFFSET 1 ROW LIMIT 2); SELECT * FROM foo WHERE EXISTS(SELECT * FROM foo OFFSET 1 ROW FETCH FIRST 2 ROWS ONLY);

警告 警告

SQL 方言检测

报告未为 SQL 文件分配方言的情况。

例如,当您打开一个新的 SQL 文件而未为其分配方言时,您会看到一条通知,建议使用最匹配的方言。 单击“使用 <dialect>”链接以使用建议的方言。 或者,单击“更改方言为”链接以选择其他方言。

警告 警告

SQL 源代码修改检测

报告数据库对象的源代码已被更改的情况。

当您执行数据库或对象内省时,将触发此检查。 当您打开对象的源代码、运行语句并执行代码重构时,会运行内省。 此外,您可以通过右键单击对象并选择“刷新”来运行内省。

此检查涵盖以下情况:

  • 对象源代码在数据库中已更改,但编辑器中的代码未更新。 适用于 PostgreSQL、Microsoft SQL Server、Oracle 和 Sybase ASE。

  • 您更改了对象源代码,内省了数据库,但源代码已被其他人更改。

  • 数据库内省器在 IDE 中已更新,您需要下载以前版本内省器中缺少的新对象属性。

警告 警告

具有副作用的语句

报告在只读连接期间可能导致数据库修改的语句。

要为连接启用只读模式,请右键单击数据库工具窗口(视图 | 工具窗口 | 数据库)中的数据源,然后选择属性。 在数据源和驱动程序对话框中,单击选项选项卡并选择只读复选框。

示例(MySQL):

CREATE TABLE foo(a INT); INSERT INTO foo VALUES (1);

由于 创建表INSERT INTO 语句会导致数据库修改,这些语句将在只读连接模式下被高亮显示。

警告 警告

触发器中的可疑代码

报告触发器中过渡表变量的错误用法。

示例(HSQLDB):

CREATE TABLE foo(a INT); CREATE TRIGGER trg AFTER DELETE ON foo BEGIN SELECT * FROM NEW; END; CREATE TRIGGER trig AFTER INSERT ON foo REFERENCING OLD ROW AS newrow FOR EACH ROW WHEN (a > 1) INSERT INTO foo VALUES (1)

在 HSQLDB 中,DELETE 触发器只能与 OLD 状态一起使用,而 INSERT 触发器只能具有 NEW 状态。 因此,在前面的示例中, SELECT * FROM NEW; 中的 NEW 和 REFERENCING OLD ROW AS newrow 中的 OLD 都将被高亮显示。

警告 警告

类型兼容性

报告与类型相关的错误。

警告 警告

SQL 中的 Unicode 使用

报告未使用 N 前缀的国家字符的字符串字面量。

如果没有 N 前缀,字符串将被转换为数据库的默认代码页。 此默认代码页可能无法识别某些字符。 有关更多信息,请参阅 nchar 和 nvarchar (Transact-SQL) at docs.microsoft.com

示例(Microsoft SQL Server):

SELECT 'abcde' AS a; SELECT N'abcde' AS b; SELECT 'абвгд' AS c; SELECT N'абвгд' AS d;

SELECT 'абвгд' AS c; 没有 N 前缀, 'абвгд' 部分将被高亮显示。

警告 警告

不可达代码

报告 SQL 例程中不可达的语句。

示例(Microsoft SQL Server):

CREATE FUNCTION foo() RETURNS INT AS BEGIN THROW; RETURN 1; END;

在 Microsoft SQL Server 中, THROW 语句引发异常并将执行转移到 TRY...CATCH 构造的 CATCH 块。 因此, RETURN 1; 部分将永远不会被执行。

警告 警告

未解析的引用

报告未解析的 SQL 引用。

示例(MySQL):

CREATE TABLE users(id INT, name VARCHAR(40)); CREATE TABLE admins(id INT, col1 INT); SELECT users.id, admins.id FROM admins WHERE admins.id > 1;

users.id 列未解析,因为 用户 表在 FROM 子句中缺失。

错误 错误

'delete' 语句中的不安全 'join' 子句

报告可能修改整个数据库的语句中缺少条件检查的情况。

例如,在 DELETE 语句中使用没有 ON 或 WHERE 的 JOIN 子句。 如果 JOIN 缺少条件检查,DELETE 将删除整个表的内容。

示例(MySQL):

CREATE TABLE foo (a INT,b INT,c INT); CREATE TABLE bar (a INT,b INT,c INT); DELETE table1 FROM foo table1 INNER JOIN bar table2;

警告 警告

未使用的公共表表达式

报告查询中未使用的公共表表达式(CTE)。

示例(PostgreSQL):

CREATE TABLE foo(a INT); WITH a AS (SELECT 1 AS x FROM foo) SELECT 1 + 2 FROM foo;

通过使用 WITH,我们创建了一个名为 a 的临时命名结果集,也称为公共表表达式(CTE)。 但我们在代码中未使用此 CTE。 未使用的 CTE 将被灰显。

警告 警告

未使用的子查询项

报告未在外部查询表达式中引用的列、别名和其他子查询项。

示例(PostgreSQL):

CREATE TABLE for_subquery(id INT); SELECT a, q FROM (SELECT 1 AS a, 10 AS b, 2 + 3 AS q, id FROM for_subquery) x;

我们从子查询中引用了 aq 别名。 但 b 别名和 iD 列未在外部 SELECT 语句中引用。 因此, biD 被灰显。

警告 警告

未使用的变量

报告未使用的参数、变量或参数。

示例(PostgreSQL):

CREATE FUNCTION foo(PARAMUSED INT, PARAMUNUSED INT) RETURNS INT AS $$ BEGIN RETURN PARAMUSED; END $$ LANGUAGE plpgsql;

PARAMUNUSED 参数未在函数中使用,可能会被删除。

警告 警告

GOTO 语句的用法

报告向后 GOTO 语句和用于退出循环的 GOTO 语句的用法。

通常不推荐广泛使用 GOTO 语句。 有关更多信息,请参阅 GOTO statement in SQL procedures at ibm.com

建议使用循环代替使用 GOTO 跳回到前一语句。

建议使用其他控制流语句(例如 RETURN 或 BREAK)代替使用 GOTO 退出 WHILE 循环。

示例(Oracle):

CREATE PROCEDURE test(n INT) AS DECLARE x INT; BEGIN x := 0; GOTO a; <<a>> x := 1; IF (n = 0) THEN GOTO a; END IF; WHILE TRUE LOOP GOTO b; END LOOP; <<b>> x := 3; END;

已禁用

在触发器中使用事务管理语句

报告在触发器主体中使用事务管理语句(如 COMMIT 或 ROLLBACK)。

如果在触发器主体中使用 COMMIT 或 ROLLBACK 语句,触发器将无法编译。 失败的原因是触发器在事务期间启动。 当触发器启动时,当前事务尚未完成。 由于 COMMIT 终止事务,COMMIT 和 ROLLBACK 语句都会导致异常。 在触发器中执行的更改应由启动触发器的所属事务提交(或回滚)。

示例(Oracle):

CREATE TABLE employee_audit ( id INT NOT NULL, update_date DATE NOT NULL, old_name VARCHAR2(100), new_name VARCHAR2(100) ); CREATE TABLE employees ( id INT NOT NULL, name VARCHAR2(100) NOT NULL ); CREATE OR REPLACE TRIGGER trig_commit AFTER UPDATE OF name ON employees FOR EACH ROW BEGIN INSERT INTO employee_audit VALUES (:old.id, SYSDATE, :old.name, :new.name); COMMIT; END; CREATE OR REPLACE TRIGGER trig_rollback AFTER UPDATE OF name ON employees FOR EACH ROW BEGIN INSERT INTO employee_audit VALUES (:old.id, SYSDATE, :old.name, :new.name); ROLLBACK; END;

警告 警告

使用 CASE 替代 COALESCE 函数及反之亦然

报告 CASE 和 COALESCE 调用可以互换的情况。 此检查具有以下意图操作:用 'COALESCE' 调用替换,或反之用 CASE 表达式替换。

示例(MySQL):

SELECT -- this CASE may be replaced by COALESCE CASE WHEN C1 IS NOT NULL THEN C1 ELSE 0 END FROM dual;

在示例中,CASE 语句可以替换为 SELECT COALESCE(C1, 0) ,产生相同的输出。

如果您更喜欢使用 CASE 表达式,请在检查页面选择“优先使用 CASE 表达式而非 COALESCE 函数”选项。

警告 警告

使用 CASE 替代条件函数及反之亦然

报告 CASE 和 IF 可以互换的情况。

示例(MySQL):

SELECT CASE WHEN C1 IS NULL THEN 1 ELSE 0 END FROM dual;

为了使代码更简洁,您可以将 CASE 结构替换为 IF。 您可以通过应用“用 'IF' 调用替换”意图操作来实现。 示例代码将如下所示:

SELECT IF(C1 IS NULL, 1, 0) FROM dual;

要将 IF 恢复为 CASE,请单击 IF 并应用“用 CASE 表达式替换”意图操作。

警告 警告

使用命名和位置参数

报告位置参数在命名参数之后的调用。 适用于 PostgreSQL、Oracle 和 Db2。

示例(PostgreSQL 中):

CREATE FUNCTION foo(a int, b int, c int) RETURNS int LANGUAGE plpgsql AS $$ BEGIN RETURN a + b + c; END $$; SELECT foo(a => 1, b => 2, c => 3); -- `3` goes after the named argument SELECT foo(1, b => 2, 3); -- `1` and `3` go after the named argument SELECT foo(b => 2, 1, 3);

错误 错误

VALUES 子句基数

报告 VALUES 中的参数数量与目标表中的列数量不匹配的情况。

示例(MySQL):

CREATE TABLE foo(a INT, b INT, c INT); INSERT INTO foo VALUES (1,2,3,4)

foo 表有三列,但在 INSERT INTO 语句中我们传递了四个。

警告 警告

最后修改日期: 2025年 9月 26日