对于为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'?
timestamp列没有计算列对象,也没有默认的sproc,但我不知何故需要知道它实际上是一个时间戳列。查看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
任何帮助都非常感激。
答案 0 :(得分: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'
似乎运行良好,但我还需要编写更多的数据类型测试:)
答案 1 :(得分:2)
关于你的第一个问题,关于默认值
select text from syscomments
where id = 602182610
对于timestamp列,syscolumns中的type
列引用systypes.type
。在该表中name
列包含数据类型名称。
答案 2 :(得分: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'