4

对于为 DBIx::Class (::Schema::Loader) 转储 Sybase 模式的 Perl 库,我需要能够自省 DEFAULT 和计算列。

假设我们有:

create table bar (
  id INTEGER IDENTITY PRIMARY KEY,
  foo VARCHAR(10) DEFAULT 'foo',
  adt AS getdate(),
  ts timestamp
)

据我所知,这是:

select substring(c.name,1,5) name, c.cdefault, c.computedcol from syscolumns c
join sysobjects o on c.id = o.id where o.name = 'bar' and o.type = 'U'

name       cdefault    computedcol 
---------- ----------- ----------- 
id                   0        NULL 
foo          602182610        NULL 
adt                  0   618182667 
ts                   0        NULL 

这告诉我,列 'foo' 有一个 id 为 602182610 的存储过程,它返回值。如何从此 id 获取原始的 DEFAULT 'foo'?

时间戳列没有计算列对象,也没有默认存储过程,但我不知何故需要知道它实际上是一个时间戳列。查看 DBI 返回的数据类型告诉我它是“varbinary”,即时间戳的内部表示。我怎么知道它是不是一个?

它还告诉我列“adt”是一个计算列,该列的对象具有 id 618182667。

在 sysobjects 中查找该 ID 并没有告诉我什么似乎有用的信息,除了:

select substring(name,1,15) name, type from sysobjects where id = 618182667

name                           type 
------------------------------ ---- 
bar_adt_6181826                C    

非常感谢任何帮助。

4

3 回答 3

6

这是我最终使用的查询,以防有人感兴趣:

SELECT c.name name, t.name type, cm.text deflt
FROM syscolumns c         
JOIN sysobjects o ON c.id = o.id
LEFT JOIN systypes t ON c.type = t.type AND c.usertype = t.usertype
LEFT JOIN syscomments cm  
  ON cm.id = CASE WHEN c.cdefault = 0 THEN c.computedcol ELSE c.cdefault END
WHERE o.name = 'table_name' AND o.type = 'U'

似乎工作得很好,虽然我仍然需要编写更多的数据类型测试:)

于 2010-01-31T14:36:55.820 回答
2

关于你的第一个问题,关于默认值

select text from syscomments 
where id = 602182610

至于时间戳列,typesyscolumns 中的列引用systypes.type. 在该表name列中包含数据类型名称。

于 2010-01-31T08:59:56.153 回答
0
SELECT o.name tab_nm,
       c.name col_nm,
       (CASE WHEN t.name is null THEN (select st.name from systypes st where st.type = c.type) ELSE t.name END) type,
       cm.text deflt,
       c.length length
FROM syscolumns c         
JOIN sysobjects o ON c.id = o.id
LEFT JOIN systypes t ON c.type = t.type AND c.usertype = t.usertype
LEFT JOIN syscomments cm  
  ON cm.id = CASE WHEN c.cdefault = 0 THEN c.computedcol ELSE c.cdefault END
WHERE o.name = 'table_name' AND o.type = 'U'
于 2020-01-02T14:27:13.680 回答