4

我尝试在 test_tbl 中添加一个新列column2并将列设置为默认值'N/A'不是 null。声明如下:

if not exists (select 1 from syscolumns where object_name(id) = 'test_tbl' and name = 'column2')
begin
  alter table test_tbl add column2 varchar(20) default 'N/A' not null
end

错误是

Could not execute statement.
Column names in each table must be unique. Column name 'column2' in table 'test_tbl' is specified more than once.
Sybase error code=2705
Severity Level=16, State=3, Transaction State=1
Line 4

但是,如果我添加一个可以为的列。

if not exists (select 1 from syscolumns where object_name(id) = 'test_tbl' and name = 'column2')
begin
    alter table test_tbl add column2 varchar(20) null
end

它可以工作。我对这些很困惑。我搜索了一些标签,知道动态 sql 可以工作。

该错误是在规范化期间引发的(因为解析树正在转换为规范化查询树),而不是在执行时。动态sql的内容在实际调用之前不会被处理,避免了错误。

在 Sybase DOC 中关于 if...else

在 if...else 块中出现 alter table、create table 或 create view 命令时, Adaptive Server 在确定条件是否为真之前为表或视图创建模式。如果表或视图已经存在,这可能会导致错误。

我想知道为什么可以为空的列语句可以无错误地执行!

4

3 回答 3

5

我在 Sybase ASE 15 上看到了相同的行为

除了您已经从 Sybase 文档中引用的内容之外,我无法为您提供解释,但是您可以通过在 execute() 语句中包装对 alter table 的调用来编写一致的行为,如下所示

if not exists (select 1 from syscolumns where object_name(id) = 'tbl_test' and name = 'column2')
begin     
    execute("
        alter table tbl_test add column2 varchar(20) default 'N/A' not null
    ")
end

我的猜测是服务器能够if...else在执行 alter 语句之前评估此实例中的语句。

于 2012-07-13T15:25:46.697 回答
0

你应该写go..

请检查下面的代码它对我来说工作正常

IF  EXISTS ( SELECT 1 FROM sysobjects WHERE name = 'a_table' AND type = 'U' )
drop table a_table
go
CREATE TABLE a_table ( col1 int not null,col2 int null )
go
于 2017-09-07T09:22:24.043 回答
0

布拉德的回答在这个版本上对我不起作用:

Adaptive Server Enterprise/16.0 SP03 PL05/EBF 28236 SMP/P/AMD64/Windows 2008 R2 SP1/ase160sp03pl05x/0/64-bit/FBO/Mon Jul 30 02:37:39 2018

(我认为如果该列过去曾存在于表中,它会返回 1)

此代码有效:

if not exists (select 1 from syscolumns where id = object_id('tbl_test') and name = 'column2')
begin     
    execute("
        alter table tbl_test add column2 varchar(20) default 'N/A' not null
    ")
end
于 2019-06-12T13:25:46.043 回答