PhpStorm 2021.3 Help

SQL 中的代码检查

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

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

检查

描述

默认严重性

添加没有默认值的非空列

报告尝试创建没有 DEFAULT 值的 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 在创建新记录时可以使用的 DEFAULT 值。
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); 选择 a, MAX(b) 从 foo GROUP BY a HAVING b > 0; SELECT * FROM foo GROUP BY a ORDER BY;

    当通过主键进行分组时,此规则不适用。

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

    从 foo 中选择一个 MAX(b) > 0; 从 foo GROUP BY MAX(a) 中选择一个;
  • 聚合函数的嵌套调用。

    从 foo 组中选择 MAX(SUM(a));

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

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

    通过 a > 0 从 foo 组中选择 a, MAX(b);

警告 警告

模棱两可的参考

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

示例(MySQL):
创建表 foo(id INT PRIMARY KEY); 创建表栏(id INT PRIMARY KEY);SELECT foo.id, bar.id FROM foo, bar WHERE id > 0;

id列出现在foobar表中。您需要限定列名以使查询正确。
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, );

AUTO_INCREMENT 约束c2将被突出显示,因为它c1已经具有此约束。要修复警告,您可以创建id主键并删除 AUTO_INCREMENT c2
CREATE TABLE my_table (id INT AUTO_INCREMENT PRIMARY KEY, c2 INT, );

警告 警告

检查使用子句列

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

示例(MySQL):
创建表 t1 (i INT, j INT); 创建表 t2 (k INT, l INT); 选择 * 从 t1 加入 t2 使用 (j);

在 USING 子句中,列名必须出现在两个表中,并且 SELECT 查询将使用给定的列名自动连接这些表。由于我们没有 in 中的jt2,我们可以使用 ON 重写查询。ON 子句可以连接两个表中列名不匹配的表。
SELECT * FROM t1 JOIN t2 ON t1.j = t2.l;

警告 警告

列被别名遮蔽

报告名称与 FROM 子句中的列名匹配的 SELECT 别名。

示例(MySQL):
创建表 foo (a INT, b INT, c INT); 从 foo 中选择 ab,c;

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

警告 警告

列应该在 group by 子句中

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

示例(Microsoft SQL Server):
创建表 t1 (a INT, b INT); 从 t1 组中选择 a、b;

如果您运行 SELECT 查询,您将收到一个错误,因为 Microsoft SQL Server 需要bGROUP BY 中的列或在聚合函数中使用该列。以下两个示例将修复该错误。
选择 a, b 从 t1 组按 a, b; SELECT a, max(b) max_b FROM t1 GROUP BY a;

警告 警告

恒定条件

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

示例(MySQL):
创建表 t1 (a TE​​XT, b INT, c BOOLEAN); SELECT a FROM t1 WHERE 'Cat' = 'Cat';

'Cat' = 'Cat'始终是真实的,并将被报告。

警告 警告

常量表达式

报告始终为真、假或空的条件和表达式。

示例(MySQL):
创建表 t1 (a TE​​XT, b INT, c BOOLEAN); SELECT a FROM t1 WHERE 'Cat' = 'Cat'; SELECT a FROM t1 WHERE 'Cat' = null;

'Cat' = 'Cat'始终是真实的,并将被报告。

始终为'Cat' = nullnull 并将被报告。

警告 警告

当前控制台模式自省

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

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

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

警告 警告

不带 where 子句的删除或更新语句

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

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

示例(MySQL):
创建表 t1 (a TE​​XT, b INT, c BOOLEAN); 更新 t1 设置 a = '史密斯'; 从 t1 中删除;

警告 警告

已弃用的类型

报告已弃用且可能在未来版本的 DBMS 中消失的类型的使用情况。

报告类型:

示例(甲骨文):
CREATE TABLE ot.foo(a NUMBER Generated by DEFAULT AS IDENTITY, b LONG NOT NULL);

警告 警告

在 SELECT 中重复列名

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

示例(Sybase ASE):
创建表 t1 (a TE​​XT, b INT, c INT); 从 t1 中选择 a 作为 x,b 作为 x;

x别名用于a和列b。这些分配被突出显示为错误,因为您不能在 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);

根据dev.mysql.com的派生表,别名是强制性的。您可以使用 Introduce alias quick-fix 添加别名。

应用快速修复后:
SELECT id AS ID, name, cats, age FROM (SELECT table1.id, name, cats, age FROM table1 JOIN table2 ON table1.id = table2.id);

警告 警告

函数签名

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

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

示例(MySQL):
创建表 foo (a INT, b INT, c INT) SELECT IFNULL() FROM foo; -- 错误 SELECT IFNULL(a) FROM foo; -- 错误 SELECT IFNULL(a, b) FROM foo; -- OK SELECT IFNULL(a, b, c) FROM foo; - 错误

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

警告 警告

标识符应该被引用

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

示例(Microsoft SQL Server):
CREATE TABLE select(身份INT IDENTITY NOT NULL,订单INT NOT NULL);

我们使用selectidentityorder作为表名和列名。但它们也是 Microsoft SQL Server 中的保留关键字。因此,为了在查询中将它们用作对象名称,您必须引用这些标识符。要引用它们,您可以使用引用标识符快速修复。

应用快速修复后:
CREATE TABLE [select] ([identity] INT IDENTITY NOT NULL, [order] INT NOT NULL);

警告 警告

格式错误的日期/时间文字

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

示例(MySQL):
从双重选择时间'10 -12:13:14';选择时间' 12 : 13 : 14 ' FROM dual; 从双重选择时间'12 13 14';从双重选择时间“12-13-14”;从双重选择时间“12.13.14”;从双重选择时间'12:13:';从双重选择时间“12:13”;从双重选择时间'12:';

在这个例子中,日期忽略了 MySQL 标准的日期和时间文字。因此,它们将被突出显示。有关 MySQL 中日期和时间文字的更多信息,请参阅dev.mysql.com 上的日期和时间文字。

以下日期和类型文字对 MySQL 有效。
从双重选择时间“12:13:14”;从双重选择时间'12:13:14.555';选择时间“12:13:14”。从双; 从双重选择时间'-12:13:14';从双重选择时间'10 12:13:14';从双重选择时间'-10 12:13:14';

警告 警告

非法游标状态

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

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

  • 例程具有 OPEN 语句,但可能会打开游标。

示例(Microsoft SQL Server):
创建表 t(col INT); CREATE PROCEDURE foo() AS BEGIN DECLARE my_cursor CURSOR FOR SELECT * FROM t; 声明一个 INT;FETCH my_cursor INTO a; 关闭 my_cursor; 结尾;

根据docs.microsoft.com 上的 CLOSE (Transact-SQL),必须在打开的游标上发出 CLOSE,并且不允许在仅已声明或已关闭的游标上发出 CLOSE。所以,我们需要打开游标来修复警告。
CREATE PROCEDURE foo() AS BEGIN DECLARE my_cursor CURSOR FOR SELECT * FROM t; 声明一个 INT;打开我的光标;FETCH my_cursor INTO a; 关闭 my_cursor; 结尾;

警告 警告

隐式字符串截断

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

示例(Microsoft SQL Server):
CREATE PROCEDURE test() AS BEGIN DECLARE myVarOk VARCHAR(5) = 'abcde'; 声明 myVarExceeded VARCHAR(5) = 'abcde12345'; SET myVarOk = 'xyz'; SET myVarExceeded = '123456789'; 结尾;

myVarExceeded变量被定义为,但VARCHAR(5)两个赋值('abcde12345''123456789')都超过了这个限制。您可以截断分配的值或增加定义的长度。要增加长度,请使用增加类型长度快速修复。

应用快速修复后:
CREATE PROCEDURE test() AS BEGIN DECLARE myVarOk VARCHAR(5) = 'abcde'; 声明 myVarExceeded VARCHAR(10) = 'abcde12345'; SET myVarOk = 'xyz'; SET myVarExceeded = '123456789'; 结尾;

警告 警告

索引取决于列

当您尝试从索引表中删除列时报告案例。此检查在 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) ); 创建唯一索引 aaaa ON test_index (col, col2); ALTER TABLE test_index DROP COLUMN col;

您不能删除该col列,因为它在索引表中。要删除列,需要先删除aaaa索引(例如,DROP INDEX aaaa)。

警告 警告

将 NULL 插入 NOT NULL 列

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

示例(Microsoft SQL Server):
创建表 br2 ( id INT NOT NULL, col1 NVARCHAR (20) NOT NULL, col2 NVARCHAR (20) NOT NULL, ); -- 插入 br2 (id, col1, col2) 值 (1, NULL, NULL);

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

警告 警告

插入生成的列

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

示例(PostgreSQL):
CREATE TABLE foo ( col1 INT, col2 INT 始终生成为 (col1 + 1) 存储); 插入 foo(col1, col2) 值 (1, 2);

您无法插入2col2列,因为该列已生成。要使此脚本正常工作,您可以更改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` 不明确,因为它用作列名和参数 SELECT COUNT(*) INTO b FROM foo t WHERE t.name = name; 返回 b; 结尾; $$ 语言 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 t WHERE t.name = name; 返回 b; 结尾; $$ 语言 plpgsql;

警告 警告

缺少列别名

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

示例(PostgreSQL):
创建表 foo(a INT, b INT); SELECT 1, a + 1 AS A2, MAX(b) AS M FROM foo;

已禁用

缺少退货声明

报告没有 RETURN 语句的函数。

示例(甲骨文):
CREATE FUNCTION foo RETURN int AS BEGIN END;

函数必须返回整foo数值,但函数体不返回任何内容。要修复错误,请添加 RETURN 语句(例如return 1;)。
CREATE FUNCTION foo RETURN int AS BEGIN RETURN 1; 结尾;

错误 错误

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

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

示例(Microsoft SQL Server):
创建表 foo(a int); select top 1 * from foo order by a offset 10 rows 仅获取接下来的 20 行;

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

警告 警告

应使用命名参数

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

有关命名参数和未命名参数之间区别的详细信息,请参阅docs.microsoft.com 上的按名称绑定参数(命名参数)

示例(Microsoft SQL Server):
CREATE FUNCTION foo(n INT, m INT) 返回 INT 作为 BEGIN RETURN n + m; 结尾; CREATE PROCEDURE 测试开始 foo n = 1, m = 2; --- 下面的调用错过了参数名称,会高亮显示 foo 1, 2; 结尾;

1, 2调用中的参数foo 1, 2;被突出显示,因为它们缺少名称。

已禁用

未配置数据源

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

警告 警告

空比较

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

示例(Microsoft SQL Server):
创建表 foo ( id int ); SELECT * FROM foo WHERE NULL = NULL; SELECT * FROM foo WHERE NULL != NULL;

NULL = NULL可以替换为IS NULL,比较NULL != NULLIS 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):
创建表 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):
选择 COALESCE(NULL, NULL, NULL, 42, NULL, 'string') 作为一个;

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

警告 警告

冗余订购方向

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

示例(MySQL):
创建表 foo(a INT, b INT, c INT); SELECT * FROM foo ORDER BY a ASC, b DESC, c ASC;

ORDER BY 关键字默认按升序对记录进行排序。因此,ASC关键字 foraccolumns 是多余的。

警告 警告

查询中的冗余行限制

报告查询中的 FETCH 和 LIMIT 等冗余行限制子句。

示例(PostgreSQL):
创建表 foo(一个 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 文件而不为其分配方言时,您会看到一条通知,其中建议了最匹配的方言。单击使用 <方言> 链接以使用建议的方言。或者,单击更改方言链接以选择其他方言。

警告 警告

SQL源修改检测

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

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

检查包括以下几种情况:
  • 数据库中的对象源代码已更改,但编辑器中的代码未更新。适用于 PostgreSQL、Microsoft SQL Server、Oracle 和 Sybase ASE。

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

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

警告 警告

有副作用的声明

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

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

示例(MySQL):
创建表 foo(一个 INT);插入 foo 值 (1);

由于CREATE TABLEINSERT INTO语句导致数据库修改,这些语句将在只读连接模式下突出显示。

警告 警告

触发器中的可疑代码

报告触发器中转换表变量的错误使用。

示例(HSQLDB):
创建表 foo(一个 INT);在 foo BEGIN SELECT * FROM NEW 上删除后创建触发器 trg;结尾; CREATE TRIGGER trig AFTER INSERT ON REFERENCING OLD ROW AS NEW ROW FOR EACH ROW WHEN (a > 1) INSERT INTO foo VALUES (1)

在 HSQLDB 中,DELETE 触发器只能用于 OLD 状态,而 INSERT 触发器可能只有 NEW 状态。因此,在前面的示例中,NEW inSELECT * FROM NEW;和 OLD in 将被突出显示REFERENCING OLD ROW AS newrow

警告 警告

类型兼容性

报告与类型相关的错误。

警告 警告

SQL 中的 Unicode 用法

报告使用不带N前缀的国家字符的字符串文字。

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

示例(Microsoft SQL Server):
选择'abcde'作为一个; 选择 N'abcde' 作为 b; 选择 'абвгд' 作为 c; 选择 N'абвгд' 作为 d;

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

警告 警告

无法访问的代码

报告 SQL 例程中无法访问的语句。

示例(Microsoft SQL Server):
CREATE FUNCTION foo() 返回 INT 作为开始抛出;返回 1;结尾;

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

警告 警告

未解决的参考

报告未解析的 SQL 引用。

示例(MySQL):
CREATE TABLE users(id INT, name VARCHAR(40)); 创建表管理员(id INT,col1 INT);SELECT users.id, admins.id FROM admins WHERE admins.id > 1;

users.id列未解析,因为usersFROM 子句中缺少该表。

错误 错误

“删除”语句中的不安全“加入”子句

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

例如,在没有 ON 或 WHERE 的 DELETE 语句中使用 JOIN 子句。如果不对 JOIN 进行条件检查,则 DELETE 会删除整个表的内容。

示例(MySQL):
创建表 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):
创建表 foo(一个 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别名。但是在外部 SELECT 语句中没有引用b别名和列。id因此,bid是灰色的。

警告 警告

未使用的变量

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

示例(PostgreSQL):
CREATE FUNCTION foo(PARAMUSED INT, PARAMUNUSED INT) 返回 INT 为 $$ BEGIN RETURN PARAMUSED; 结束 $$ 语言 plpgsql;

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

警告 警告

GOTO 语句的用法

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

一般不建议大量使用 GOTO 语句。有关详细信息,请参阅ibm.com 上 SQL 过程中的 GOTO 语句

与其使用 GOTO 跳回上一条语句,不如考虑使用循环。

不要使用 GOTO 退出 WHILE 循环,而是考虑使用其他流控制语句(例如,RETURN 或 BREAK)。

示例(甲骨文):
CREATE PROCEDURE test(n INT) AS DECLARE x INT; 开始 x := 0; 转到一个; <<a>> x := 1; 如果 (n = 0) 然后转到 a; 万一; WHILE TRUE 循环转到 b; 结束循环;<<b>> x := 3; 结尾;

已禁用

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

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

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

示例(甲骨文):
CREATE TABLE employee_audit (id INT NOT NULL, update_date DATE NOT NULL, old_name VARCHAR2(100), new_name VARCHAR2(100)); CREATE TABLE 员工(id INT NOT NULL,姓名 VARCHAR2(100) NOT NULL);在每行更新员工姓名后创建或替换触发器 trig_commit 插入employee_audit VALUES (:old.id, SYSDATE, :old.name, :new.name); 犯罪; 结尾; 在每行更新员工姓名后创建或替换触发器 trig_rollback 开始插入employee_audit VALUES (:old.id, SYSDATE, :old.name, :new.name); 回滚;结尾;

警告 警告

使用 CASE 而不是 COALESCE 函数,反之亦然

报告 CASE 和 COALESCE 调用可互换的情况。此检查具有以下意图操作:替换为“COALESCE”调用和相反的替换为 CASE 表达式。

示例(MySQL):
SELECT -- 这个 CASE 可以被 COALESCE CASE 替换 WHEN C1 IS NOT NULL THEN C1 ELSE 0 END FROM dual;

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

如果您更喜欢使用 CASE 表达式,请在检查页面上选择 Prefer CASE 表达式而不是 COALESCE 函数选项。

警告 警告

使用 CASE 而不是条件函数,反之亦然

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

示例(MySQL):
SELECT CASE WHEN C1 IS NULL THEN 1 ELSE 0 END FROM dual;

为了保持代码简短,可以将 CASE 结构替换为 IF。您可以通过应用 Replace with 'IF' 呼叫意图操作来做到这一点。示例代码如下所示:
选择 IF(C1 IS NULL, 1, 0) FROM dual;

要将 IF 恢复为 CASE,请单击 IF 并应用 Replace with CASE 表达式意图操作。

警告 警告

使用命名参数和位置参数

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

示例(在 PostgreSQL 中):
CREATE FUNCTION foo(a int, b int, c int) RETURNS int LANGUAGE plpgsql AS $$ BEGIN RETURN a + b + c; 结束$$; 选择 foo(a => 1, b => 2, c => 3); -- `3` 在命名参数之后 SELECT foo(1, b => 2, 3); -- `1` 和 `3` 在命名参数之后 SELECT foo(b => 2, 1, 3);

错误 错误

VALUES 子句基数

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

示例(MySQL):
创建表 foo(a INT, b INT, c INT); 插入 foo 值 (1,2,3,4)

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

警告 警告

最后修改:2022 年 2 月 11 日