Oracle如何在将一个数据库中的所有表都加上某些字段。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle如何在将一个数据库中的所有表都加上某些字段。相关的知识,希望对你有一定的参考价值。

1.如何查出数据库中所有表中不包含MODIFIER字段的表,
select distinct
TABLE_NAME from user_tab_columns a
where a.COLUMN_NAME <> 'MODIFIER' 得到的值为什么不正确。

2.我如何将得到的一组表同时加上MODIFIER NVARCHAR2(120)字段,即用得到的表结果集来替换下列语句中的表名。
declare
vstr_sql varchar2(2000):='alter table 表名 add MODIFIER NVARCHAR2(120) not null)';
begin
execute immediate vstr_sql;
end;
希望各位指教,3Q.

需要用存储过程解决。

如数据库中存在两张表,要给两张表都增加两个同样名称同样属性的字段,需要用以下代码:

1、创建测试用表test和test1

create table test
(id int,
name varchar2(10));

create table test1
(id int,
name varchar2(10));

2、要为两个表同时增加id1和name1字段。使用代码:

declare 
v_sql varchar2(2000);
v_table_name varchar2(30);
cursor c1 is select table_name from user_tables;
begin
open c1;
loop --提取一行数据到c1
fetch c1 into v_table_name;
--判读是否提取到值,没取到值就退出
--取到值c_job%notfound 是false 
--取不到值c_job%notfound 是true
exit when c1%notfound;
v_sql:=\'alter table \'||v_table_name||\' add id1 int\';
execute immediate v_sql;
v_sql:=\'alter table \'||v_table_name||\' add name1 varchar2(10)\';
execute immediate v_sql;
end loop;--关闭游标
close c1;
end;

如图:

3、执行代码,成功无误后,查询test表和test1表结构:

参考技术A 你的思路有点不准确,使用下面的语句就没有问题了
select distinct a.TABLE_NAME from user_tab_columns a where a.TABLE_NAME not in (SELECT b.TABLE_NAME from user_tab_columns b where b.COLUMN_NAME=‘MODIFIER’);
仔细想想你就明白为什么你写的不对了,希望能够解答你的疑惑。

提示:你并没有把包含指定列的表的情况除去追问

我没弄清楚user_tab_columns视图包含的字段意义,谢谢了!现在理清楚了。

追答

嗯,思路很重要

参考技术B declare
vstr_sql varchar2(2000);
cursor c1 is select distinct a.TABLE_NAME TABLE_NAME from user_tab_columns a
where a.TABLE_NAME not in (SELECT b.TABLE_NAME from user_tab_columns b where b.COLUMN_NAME=‘MODIFIER’);
begin
for rec in c1 loop
vstr_sql varchar2(2000):='alter table '||rec.TABLE_NAME||' add MODIFIER NVARCHAR2(120) not null)';
execute immediate vstr_sql;
end loop;
end;本回答被提问者采纳

如果所有表都不存在,请添加一列?

【中文标题】如果所有表都不存在,请添加一列?【英文标题】:Add a column if it doesn't exist to all tables? 【发布时间】:2011-07-05 23:42:45 【问题描述】:

我使用的是 SQL Server 2005/2008。如果表尚不存在,我需要向表中添加一列。这将适用于给定数据库中的所有表。我希望我很接近,但我遇到了这个解决方案的问题。

如何做到这一点?

这是我所拥有的:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE @tblname ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'

但我得到错误:

错误 102:“@tblname”附近的语法不正确。 “CreatedOn”附近的语法不正确。 '@tblname' 附近的语法不正确。 “CreatedOn”附近的语法不正确。 ... 等等,对于每个表。

【问题讨论】:

***.com/questions/1779743/… 的可能重复项 @JAiro:这绝对是一个相关的链接,但是“如果不存在”规则很重要,并且让它变得更复杂一些。 好的,你可以用这个来完成信息:***.com/questions/133031/… 您问题的根本原因是依赖于 INFORMATION_SCHEMA 视图并且必须将名称拆分为模式和对象。只需使用object_id(''?'') 就可以了。更快的检查是if COLUMNPROPERTY(object_id(''?''), ''CreatedOn'', ''ColumnId'') is null 【参考方案1】:

您不能在 DDL 中使用变量,例如 @tableName。此外,将名称分成部分并忽略模式只会导致错误。您应该只在 SQL 批处理参数中使用 ''?'' 替换并依赖 MSforeachtable 替换:

EXEC sp_MSforeachtable '
if not exists (select * from sys.columns 
               where object_id = object_id(''?'')
               and name = ''CreatedOn'') 
begin
    ALTER TABLE ? ADD CreatedOn datetime NOT NULL DEFAULT getdate();
end';

【讨论】:

请记住,sp_msforeachtable 是不受支持的存储过程,因此不应将其用于生产代码。尽管它添加了几行代码,但如果您使用定义为从 sys.schemas 和 sys.tables 中选择的 游标,则您使用的是 T-SQL 的文档化部分,您可以选择只改变一个WHERE表达式就可以影响全部或部分表,性能是一样的。此外,如果您使用 quotename 函数,您可以处理更少的名称限定符。最后,您可以更灵活地使用您希望的架构/表名称(即用于日志)。 @PhilHelmer 这连同一个例子会是一个很好的答案。【参考方案2】:

您需要混合一些动态 SQL。这应该有效:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);
    declare @sql nvarchar(1000);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        set @sql = N''ALTER TABLE '' +  @tblname + N'' ADD CreatedOn datetime NOT NULL DEFAULT getdate();''
        exec sp_executesql @sql
    end
'

【讨论】:

@Remus:是的,如果 OP 正在使用模式,那么这将成为一个问题。为您的回答 +1。【参考方案3】:

DECLARE @Column VARCHAR(100) = 'Inserted_date'
DECLARE @sql VARCHAR(max) = NULL

SELECT @sql += ' ALTER TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + 'ADD' + @Column + 'datetime NOT NULL DEFAULT getdate()' + '; '
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
    AND TABLE_NAME IN (
        SELECT DISTINCT NAME
        FROM SYS.TABLES
        WHERE type = 'U'
            AND Object_id IN (
                SELECT DISTINCT Object_id
                FROM SYS.COLUMNS
                WHERE NAME != @Column
                )
        )
EXEC Sp_executesql @sql

【讨论】:

考虑为您的答案添加解释。也许也删除代码的屏幕截图...... 嗨,Jean,实际上我只是将列名存储在一个变量中,并找出该特定列不存在的表名,然后将 alter 命令保存在另一个变量 @sql 中我们运行执行添加。【参考方案4】:

可能是这样的:

EXEC sp_MSforeachtable '
    declare @tblname varchar(255);
    SET @tblname =  PARSENAME("?",1);

    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = @tblname and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'

?

甚至像这样:

EXEC sp_MSforeachtable '
    if not exists (select column_name from INFORMATION_SCHEMA.columns 
                   where table_name = ''?'' and column_name = ''CreatedOn'') 
    begin
        ALTER TABLE [?] ADD CreatedOn datetime NOT NULL DEFAULT getdate();
    end
'

【讨论】:

-1 在发布之前显然没有对此进行测试。 [?] 在已经用括号括起来的名称周围添加括号,导致 [[schemaname].[tablename]] 这是不正确的。 @Remus Rusanu:我对此进行了测试:sp_MSforeachtable 'EXEC sp_help ?; EXEC sp_columns ?'。这给出了语法错误。然后我把它改成sp_MSforeachtable 'EXEC sp_help [?]; EXEC sp_columns [?]',它工作了(SQL Server 2008 R2)。 ...但是您没有测试 OP ALTER TABLE [?]sp_helpsp_columns 都是存储过程,? 替换不起作用,因为 sp_help [foo].[bar] 是无效语法。但是sp_help [[foo]].[bar]]] 是正确的语法,并且由于参数的处理方式,它实际上最终可以工作。 ALTER TABLE [[foo]].[bar]]] 虽然不起作用。长话短说:您发布的代码没有通过基本的语法检查,任何人都可以验证。 @Remus Rusanu:我不是在争论。我发布我的测试示例有两个原因:提供我错觉的原因,并可能有人解释我为什么会被错觉(除了我无知的明显原因)。所以,最后,谢谢。 :) 哦,对不起,我误解了你的 cmets。 sp_help [?] 的工作方式至少对我来说也很神秘。

以上是关于Oracle如何在将一个数据库中的所有表都加上某些字段。的主要内容,如果未能解决你的问题,请参考以下文章

在具有四个表的Oracle数据库中创建视图,每个表都有主键

如何查询一个oracle数据库中所有表的所有字段哪个包含特定字符串?

数据库

如何用PowerDesigner逆向工程导出ORACLE数据库表结构

oracle 中的过程中的某些 ID 不显示数据

oracle 优化方案小记