【问题标题】:In sybase ASE, Unable to insert using Proxy_table Command在 sybase ASE 中,无法使用 Proxy_table 命令插入
【发布时间】:2020-12-19 20:52:41
【问题描述】:

我正在使用 Sybase ASE 15.7 并且在使用默认值插入代理表时遇到问题。我们希望将数据从源表迁移到目标表,其中目标表在远程服务器中具有不为空和默认值的附加列。请查看下表详细信息。

源表:

CREATE TABLE TABLE_SOURCE
(
COL1 INT,
COL2 INT,
COL3 INT
) 

目标表:

CREATE TABLE TABLE_TARGET
(COL1 INT,
COL2 INT,
COL3 INT,
COL4 INT Default 0 NOT NULL
) 

在源数据库中创建代理表:

CREATE Proxy_Table TAB_TARGET AT 'TGT_SERVER.DB.DBO.TABLE_TARGET' 

在 Source 中,我们有三列的详细信息,我们用它来构建 Query。

脚本:

INSERT INTO TAB_TARGET (COL1,COL2,COL3) values (1,2,3) 

错误:

The column COL4 in table TAB_TARGET does not allow null values., Error 233, Line 1 

虽然我们已经为 COL4 声明了默认的 costraint,但它不接受通过代理表。有什么办法可以解决这个问题。我们有超过 5000 个用户正在迁移数据的表,并且这个问题存在于 100 多个表中。

有什么方法可以插入目标表而不出现 NOT NULL 问题

【问题讨论】:

    标签: sybase sap-ase


    【解决方案1】:

    Reference Manual: Commands: create proxy_tableUsage 部分显示以下内容:

    "create proxy_table 不导入列默认值和规则;使用 创建现有表,其中列属性可以 已定义。”

    注意:此参考来自 ASE 16 手册;我在 ASE 15.7 SP100 手册中找不到此评论;我假设在编写 ASE 15.7 手册时忽略了这个细节。


    由于您要处理大量表,我假设您已经准备好一些脚本来加快迁移过程(并尽量减少手动创建 5K 代理表和相关的 INSERT 语句)。

    如果这个假设是正确的,并且您不希望创建 5K create existing table 命令的麻烦(完成所有那些讨厌的列详细信息),我想知道它是否会(相对)更容易生成具有显式默认值的 INSERT 语句,例如:

    INSERT INTO TAB_TARGET (COL1,COL2,COL3,COL4) values (1,2,3,0) 
    

    至于如何在系统表中找到默认值……

    • 如果列具有默认值,则 syscolumns 中的关联记录 将在 cdefault 列中存储一个非零值,即 syscolumns.cdefault > 0
    • 非零 cdefault 值是指向 syscmets 中存储默认信息的记录的指针,即 syscolumns.cdefault = syscmets.id.
    • 实际的默认值存储在 syscmets.text 列中 两种格式之一,取决于默认是否为 a) 内联定义 作为 create/alter table 命令的一部分或 b) 通过 create default 命令定义为独立默认值。

    例子:

    -- inline default value of '0' assigned to column 'b'
    create table t1 (a int, b int default 0 not null, c int)
    go
    
    -- standalone default named 'myzero' with default value of '0'; bound to column 'c'
    create default myzero as 0
    go
    sp_bindefault myzero, 't1.c'
    go
    
    sp_help t1
    go
    ...
     Column_name ... Default_name
     ----------- ... --------------
     a           ... NULL          
     b           ... t1_b_467529718             -- inline default
     c           ... myzero                     -- standalone default
    ...
    
    -- contents of syscolumns.cdefault
    select name, cdefault from syscolumns where id = object_id('t1') order by colid
    go
     name       cdefault
     ---------- -----------
     a                    0
     b            467529718
     c            387529433
    
    -- contents of syscomments.text
    select id,text from syscomments where id in (467529718,387529433) order by id
    go
     id        text
     --------- ---------------------------
     467529718 DEFAULT  0                       -- inline default
     387529433 create default myzero as 0       -- standalone default
    
    -- pulling this all together:
    
    select col.name, com.text
    from   syscolumns  col,
           syscomments com
    where  col.id = object_id('t1')
    and    col.cdefault = com.id
    order by 1
    go
     name       text
     ---------- ------------------------------
     b          DEFAULT  0                      -- inline default
     c          create default myzero as 0      -- standalone default
    

    从这里您应该能够根据 syscmets.text 列的格式和实际的默认值(即,它是数字吗?它是一个字符串,可能有嵌入空间?它是一个函数引用,例如,getdate())。

    【讨论】:

    • 谢谢,马克。是的,我可以知道如何使用 SQL Query 从 Sybase ASE 获取列的默认值吗?
    • 答案更新了有关在系统表中查找默认值的详细信息
    猜你喜欢
    • 2014-08-29
    • 2017-10-07
    • 2013-05-29
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多