编辑: 我尝试了这段代码,这是用户提到的一部分,它正确地返回了字段。
SELECT * FROM INFORMATION_SCHEMA.TABLES
JOIN INFORMATION_SCHEMA.COLUMNS on
INFORMATION_SCHEMA.TABLES.TABLE_NAME =
INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'
前一个查询中的某些内容适用于某些数据库但不适用于其他数据库
编辑2:
我已尝试按照用户的建议设置 Profiler 跟踪以检查通过向导创建的列。显然,它使用相同的模式。
ALTER TABLE dbo.table1 ADD
field2 nchar(10) NULL
我正在使用 SQL Server 2014,并使用向导创建数据库,我的意思是,不是通过代码,而是通过使用 UI。
然后,我尝试获取有关其表列的元数据信息……但没有返回任何结果。我查询 INFORMATION_SCHEMA。
我试过对我通过代码创建的数据库使用相同的查询,它工作正常,它返回列及其值等。
我尝试在互联网上查找它,但似乎想不出适合此类情况的任何内容。我认为它与通过代码和通过 UI 创建的列有所不同有点奇怪。如果有人知道为什么会发生这样的事情,或者看起来很熟悉,我将不胜感激 :)
这是我用来检索列元数据的代码:
USE 'database'
SELECT infSch.TABLE_CATALOG,
infSch.TABLE_NAME,
sysCols.name,
infSch.ORDINAL_POSITION,
sysCols.is_nullable,
infSch.DATA_TYPE,
infSch.CHARACTER_MAXIMUM_LENGTH,
sysCols.is_identity,
IIF(infSchCons.CONSTRAINT_TYPE = 'PRIMARY KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'FOREIGN KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'UNIQUE', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'CHECK', 1, 0)
FROM sys.columns as sysCols
RIGHT JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name =
infSch.COLUMN_NAME
RIGHT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on
infSch.TABLE_NAME = infSchCons.TABLE_NAME
结果:
如果表和列是由代码创建的 --> 它返回给定数据库的所有列及其元数据
如果表和列是使用 UI 和窗口创建的 --> 它不返回任何内容,只是一组空结果
最佳答案
右连接改变了查询的性质,它们总是可以通过颠倒表的顺序来重写。避免正确的连接....试试这个:
SELECT infSch.TABLE_CATALOG,
infSch.TABLE_NAME,
sysCols.name,
infSch.ORDINAL_POSITION,
sysCols.is_nullable,
infSch.DATA_TYPE,
infSch.CHARACTER_MAXIMUM_LENGTH,
sysCols.is_identity,
IIF(infSchCons.CONSTRAINT_TYPE = 'PRIMARY KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'FOREIGN KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'UNIQUE', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'CHECK', 1, 0)
FROM sys.columns as sysCols
LEFT JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name =
infSch.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on
infSch.TABLE_NAME = infSchCons.TABLE_NAME
该查询不会将结果限制为仅存在约束的结果。
尝试比较这些:
select count(*) from (
SELECT
infSchCons.*
FROM sys.columns as sysCols
right JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name = infSch.COLUMN_NAME
right JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on infSch.TABLE_NAME = infSchCons.TABLE_NAME
) x
;
select count(*) from (
SELECT
infSchCons.*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS infSchCons
left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME
left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name
) x
;
最后一个查询是对原始 from 子句的重写,在这里(在我看来)更容易看出您必须对要返回的任何行具有约束。
编辑
问题询问为什么特定查询在某些数据库中不起作用。
该查询使用 RIGHT OUTER JOINS
由于连接类型的操作方式,它改变了表的优先级——这可能会造成混淆
因为所有正确的连接都可以“反转”,所以当您执行等效查询(对原始查询)时,有一个这样的 from 子句:
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS infSchCons left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name
所以优先级最高的表是INFORMATION_SCHEMA.TABLE_CONSTRAINTS
,如果该表中没有行,查询将不会返回任何数据。
在对问题的第二次编辑中,有一个有效的查询:
SELECT * FROM INFORMATION_SCHEMA.TABLES JOIN INFORMATION_SCHEMA.COLUMNS ON INFORMATION_SCHEMA.TABLES.TABLE_NAME = INFORMATION_SCHEMA.COLUMNS.TABLE_NAME WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'
并且:这个“有效”是因为具有最高优先级的表是 INFORMATION_SCHEMA.TABLES
,几乎可以保证其中有行。
因此,原始查询使用了错误的最高优先级表,由于正确的连接而被掩盖了。有效的查询使用一个合理的表作为其基表,并且不使用右连接。
关于sql-server - 令人困惑的行为 - 使用向导创建的 SQL Server 信息架构和列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53696807/