3

我正在尝试列出我选择的 Adventureworks 表中的所有列。我可以执行什么 T-SQL 语句或存储过程来查看所有列的列表?我想使用我的 C# Web 应用程序输入一个输入参数 = table_name,然后获取所有 column_names 的列表作为输出。现在我正在尝试执行 sp_columns 存储的过程,它可以工作,但我不能只得到一个结合了 select 和 exec 的列。有人知道怎么做这个吗?

感谢大家的所有回复,但您的回答都没有满足我的需求。让我为你解释一下我的问题。下面的查询返回我需要的内容。但我的问题是将这个逻辑合并到一个带有输入参数的 SP 中。所以这里是成功的SQL语句:

select col.name from sysobjects obj inner join syscolumns col 
    on obj.id = col.id
    where obj.name = 'AddressType' 
     order by obj.name

目前我的 SP 看起来像:

CREATE PROCEDURE [dbo].[getColumnNames]
    @TableName VarChar(50)
    AS

    BEGIN
    SET NOCOUNT ON;
    SET @TableName = RTRIM(@TableName)
    DECLARE @cmd AS NVARCHAR(max)
    SET @cmd = N'SELECT col.name from sysobjects obj ' +
    'inner join syscolumns col on obj.id = col.id ' +
    'where obj.name = ' + @TableName
    EXEC sp_executesql @cmd
    END

但我将上述内容运行为

exec getColumnNames 'AddressType'

它给了我错误:

Invalid column name 'AddressType'

我该如何做到这一点?

4

6 回答 6

8
select * from sys.columns where object_id = object_id(@tablename);
于 2010-04-08T20:27:39.997 回答
5

您不需要将语句创建为字符串——事实上,这就是让您感到困惑的原因。尝试这个:

CREATE PROCEDURE [dbo].[getColumnNames] @TableName VarChar(50) AS

BEGIN
SET NOCOUNT ON;
SELECT col.name FROM sysobjects obj 
INNER JOIN syscolumns col ON obj.id = col.id 
WHERE obj.name = @TableName
END
于 2010-04-08T21:22:35.970 回答
3

to display info for database.dbo.yourtable try this:

SELECT
    *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE 
        TABLE_CATALOG   ='database'
        AND TABLE_SCHEMA='dbo'
        AND TABLE_NAME  ='yourtable'
    ORDER BY ORDINAL_POSITION

EDIT based on OP's edit

You don't need dynamic sql, just use the given parameter:

CREATE PROCEDURE [dbo].[getColumnNames]
@TableName VarChar(50)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Rows         int
           ,@ReturnValue  int
    SET @ReturnValue=0
    SELECT
        col.name 
        FROM sysobjects            obj 
            inner join syscolumns  col on obj.id = col.id 
        WHERE obj.name = @TableName
        ORDER BY obj.name
    SELECT @Rows=@@ROWCOUNT
    IF @Rows=0
    BEGIN
        SET @ReturnValue= 1  --table not found!!
    END
    RETURN @ReturnValue 

END

if you check the return value and get a 1 then no table was found matching the given @TableName parameter. You can use this to give a error message in the application.

于 2010-04-08T20:39:59.833 回答
2
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND TABLE_CATALOG = 'DatabaseName'
于 2010-04-08T20:39:30.757 回答
1

回复您编辑的问题:

您的脚本不起作用,因为您正在构建一个动态字符串,并且在该动态字符串中,您必须将引号添加到放置在 where 子句中的字符串。修改后的代码将是:

BEGIN 
SET NOCOUNT ON; 
SET @TableName = RTRIM(@TableName) 
DECLARE @cmd AS NVARCHAR(max) 
SET @cmd = N'SELECT col.name from sysobjects obj ' + 
'inner join syscolumns col on obj.id = col.id ' + 
'where obj.name = ''' + @TableName + ''''
EXEC sp_executesql @cmd 
END 

但是,为什么要构建动态字符串?这将做同样的事情,并且不需要动态 SQL 的开销:

BEGIN 
SET NOCOUNT ON; 
SET @TableName = RTRIM(@TableName) 
SELECT col.name from sysobjects obj
inner join syscolumns col on obj.id = col.id
where obj.name = @TableName 
END 

如果您担心 SQL 注入,这不是问题——要么 obj.name =(无论他们传入什么),要么没有。

于 2010-04-08T21:19:51.967 回答
1

使用 Remus Rusanu 答案或使用SqlConnection.GetSchema()c# 代码中的函数

于 2010-04-08T20:34:50.363 回答