Pergunta

Estou tentando listar todas as colunas da tabela AventureWorks que eu escolher. Qual instrução T-SQL ou PROC armazenado posso executar para ver esta lista de todas as colunas? Quero usar meu aplicativo C# para inserir um parâmetro de entrada = tabela_name e, em seguida, obtenha uma lista de todos os colunas_names como saída. No momento, estou tentando executar o SP_COLUNS Stored Proc, que funciona, mas não consigo obter apenas a coluna com seleção e executado. Alguém sabe como fazer isto?

Obrigado a todos por todas as suas respostas, mas nenhuma das suas respostas faz o que eu preciso. Deixe -me explicar mais meu problema para você. A consulta abaixo retorna o que eu preciso. Mas meu problema é incorporar essa lógica em um SP que pega um parâmetro de entrada. Então, aqui está a instrução SQL bem -sucedida:

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

E atualmente meu SP parece:

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

Mas eu corro o acima como

exec getColumnNames 'AddressType'

E isso me dá erro:

Invalid column name 'AddressType'

Como faço isso?

Foi útil?

Solução

Você não precisa criar a declaração como uma string - na verdade, é isso que está bagunçando você. Experimente isso:

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

Outras dicas

select * from sys.columns where object_id = object_id(@tablename);

Para exibir informações para database.dbo.yourtable Experimente isso:

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

EDITAR com base na edição do OP

Você não precisa de SQL dinâmico, basta usar o parâmetro fornecido:

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

Se você verificar o valor de retorno e obter um 1, nenhuma tabela foi encontrada correspondendo ao parâmetro @TableName fornecido. Você pode usar isso para fornecer uma mensagem de erro no aplicativo.

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND TABLE_CATALOG = 'DatabaseName'

Use Remus Rusanu Responder ou usar SqlConnection.GetSchema() função do seu código C#

Uma resposta ao seu editado pergunta:

Seu script não funciona porque você está criando uma string dinâmica e, dentro dessa sequência dinâmica, você deve adicionar cotações à string que está colocando na sua cláusula onde. O código revisado seria:

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 

No entanto, por que você está belidindo uma string dinâmica? Isso faria a mesma coisa e não exigiria a sobrecarga do SQL dinâmico:

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 

Se você está preocupado com a injeção de SQL, não é um problema aqui - ou obj.name = (o que quer que eles passaram), ou não.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top