oracle T-SQL和PL/SQL查询,用于检查表中是否存在列以及是否存在;在where子句中使用它

v7pvogib  于 2023-08-03  发布在  Oracle
关注(0)|答案(1)|浏览(83)

我在t-sql中有一个查询,它检查表中是否存在column,如果它确实用where子句中的列查询表,如果不存在,那么查询就不同了。
1.还有比这更好的解决方案吗?
1.在Oracle PL/SQL中是否可以重新创建此功能?

--check if dbo.table.UPDATE_STAMP exists
IF COL_LENGTH('dbo.table', 'UPDATE_STAMP') IS NULL
BEGIN
--if dbo.table.UPDATE_STAMP does not exist
    SELECT * FROM dbo.table where CREATE_STAMP > GETDATE()
END
ELSE
BEGIN
--if dbo.table.UPDATE_STAMP does exist
     EXEC('SELECT * FROM dbo.table WHERE UPDATE_STAMP > GETDATE()')
END

字符串

pwuypxnk

pwuypxnk1#

免责声明

这种设计不是很自然(至少在Oracle中是这样),因为您要么在数据模型中有列,并且可以硬编码它,知道它在模型定义中扮演什么角色,要么您没有列,并且您不能保证如果几年后有人添加它,它的含义也是一样的。为了便于维护,最好是让代码静态化,并在模型发生变化时对其进行更改,而不是让动态SQL自动适应变化。

答案

您可以使用SQL宏(自版本19.7起可用)。
如果你不想为每个表创建一个函数,那么你可以在with function块中本地声明这个函数,但是同一个查询应该总是返回相同的表形状,所以如果你在同一个会话中添加/删除列并再次执行查询(或者你必须指定列列表而不使用*),这可能是一个问题。
设置:

create table test(id, val, dt)
as
select level, lpad(level, 3, '0'), sysdate - level
from dual
connect by level < 6

字符串
查询1:

with function f_dyn_sql
  return clob
  sql_macro(table)
as
  lv_col_exists int := 0;
  lv_stmt varchar2(100) := q'{select id, val from test where 1 = 1}';
begin
  select count(1)
    into lv_col_exists
  from user_tab_cols
  where table_name = 'TEST'
    and column_name = 'DT';

  if lv_col_exists > 0 then
    lv_stmt := lv_stmt || ' and dt > sysdate - 3';
  end if;

  return lv_stmt;
end;

select *
from f_dyn_sql()


| 瓦尔| VAL |
| --| ------------ |
| 001| 001 |
| 002| 002 |
然后删除该列并重新执行查询:

update test
set dt = null

x

5 rows affected
alter table test
drop column dt
with ... <the same code>

select *
from f_dyn_sql()

的一个或多个字符
| 瓦尔| VAL |
| --| ------------ |
| 001| 001 |
| 002| 002 |
| 零零三| 003 |
| 零零四| 004 |
| 005| 005 |
fiddle

相关问题