查找具有特定值的表、列
Find tables, columns with specific value
我正在使用 Firebird 2.5.0。我知道一个值,需要找到它出现的所有 table 列。
我创建了程序:
CREATE OR ALTER PROCEDURE NEW_PROCEDURE (
searching_value varchar(30))
returns (
table_with_value varchar(100),
column_with_value varchar(100))
as
declare variable all_tables varchar(50);
declare variable all_columns varchar(50);
declare variable all_values varchar(50);
begin
FOR SELECT
r.rdb$relation_name, f.rdb$field_name
from rdb$relation_fields f
join rdb$relations r on f.rdb$relation_name = r.rdb$relation_name
and r.rdb$view_blr is null
and (r.rdb$system_flag is null or r.rdb$system_flag = 0)
order by 1, f.rdb$field_position INTO :all_tables, :all_columns
DO
BEGIN
FOR SELECT all_columns FROM all_tables
INTO :all_Values
DO
BEGIN
IF (SEARCHING_VALUE = all_Values) THEN
BEGIN
table_With_Value = all_Tables;
column_With_Value = all_Columns;
SUSPEND;
END
END
END
END^
当我 运行 它时,我收到错误消息:
未定义的名称。
动态SQL错误。
SQL 错误代码 = -204。
Table 未知。
ALL_TABLES。
第 21 行第 13 列。
所以在这个 select 语句 "SELECT all_columns FROM all_tables" 中,它没有从之前的 for select 语句中获取值,而是试图找到 table all_tables。如何解决?
问题是 all_columns
被认为是列名称,all_tables
被认为是 table 名称,而不是您的变量:
SELECT all_columns FROM all_tables
您不能在这样的查询中参数化对象名称。另请注意,如果可以参数化对象名称,则必须使用 :all_columns
和 :all_tables
来消除歧义。
相反,您需要创建动态 SQL 语句并使用 EXECUTE STATEMENT
(or more specifically: FOR EXECUTE STATEMENT
).
执行该语句
在这种情况下:
FOR EXECUTE STATEMENT 'SELECT "' || all_columns || '" FROM "' || all_tables || '"'
INTO :all_values
DO
BEGIN
/* .... */
END
我引用了对象名称以说明区分大小写的列和 table 名称(或未加引号的无效标识符)。如果值是从 Firebird 元数据 tables.tables.
以外的其他来源获取的,那么构建这样的查询可能会使您面临 SQL 注入
我正在使用 Firebird 2.5.0。我知道一个值,需要找到它出现的所有 table 列。
我创建了程序:
CREATE OR ALTER PROCEDURE NEW_PROCEDURE (
searching_value varchar(30))
returns (
table_with_value varchar(100),
column_with_value varchar(100))
as
declare variable all_tables varchar(50);
declare variable all_columns varchar(50);
declare variable all_values varchar(50);
begin
FOR SELECT
r.rdb$relation_name, f.rdb$field_name
from rdb$relation_fields f
join rdb$relations r on f.rdb$relation_name = r.rdb$relation_name
and r.rdb$view_blr is null
and (r.rdb$system_flag is null or r.rdb$system_flag = 0)
order by 1, f.rdb$field_position INTO :all_tables, :all_columns
DO
BEGIN
FOR SELECT all_columns FROM all_tables
INTO :all_Values
DO
BEGIN
IF (SEARCHING_VALUE = all_Values) THEN
BEGIN
table_With_Value = all_Tables;
column_With_Value = all_Columns;
SUSPEND;
END
END
END
END^
当我 运行 它时,我收到错误消息:
未定义的名称。
动态SQL错误。
SQL 错误代码 = -204。
Table 未知。
ALL_TABLES。
第 21 行第 13 列。
所以在这个 select 语句 "SELECT all_columns FROM all_tables" 中,它没有从之前的 for select 语句中获取值,而是试图找到 table all_tables。如何解决?
问题是 all_columns
被认为是列名称,all_tables
被认为是 table 名称,而不是您的变量:
SELECT all_columns FROM all_tables
您不能在这样的查询中参数化对象名称。另请注意,如果可以参数化对象名称,则必须使用 :all_columns
和 :all_tables
来消除歧义。
相反,您需要创建动态 SQL 语句并使用 EXECUTE STATEMENT
(or more specifically: FOR EXECUTE STATEMENT
).
在这种情况下:
FOR EXECUTE STATEMENT 'SELECT "' || all_columns || '" FROM "' || all_tables || '"'
INTO :all_values
DO
BEGIN
/* .... */
END
我引用了对象名称以说明区分大小写的列和 table 名称(或未加引号的无效标识符)。如果值是从 Firebird 元数据 tables.tables.
以外的其他来源获取的,那么构建这样的查询可能会使您面临 SQL 注入