54
create procedure sp_First
@columnname varchar
AS
begin
select @columnname from Table_1
end 
exec sp_First 'sname'

我的要求是将列名作为输入参数传递。我试过这样,但它给出了错误的输出。

所以帮助我

4

9 回答 9

75

你可以通过几种方式做到这一点。

一是自己构建查询并执行它。

SET @sql = 'SELECT ' + @columnName + ' FROM yourTable'
sp_executesql @sql

如果您选择该方法,请务必确认您的输入。即使您知道您的应用程序只会给出“真实”的列名,但如果有人发现您的安全漏洞并能够直接执行 SP 怎么办?然后他们可以执行他们喜欢的任何事情。使用动态 SQL,always、always验证参数。

或者,您可以编写 CASE 语句...

SELECT
  CASE @columnName
    WHEN 'Col1' THEN Col1
    WHEN 'Col2' THEN Col2
                ELSE NULL
  END as selectedColumn
FROM
  yourTable

这有点冗长,但更安全。

于 2012-04-10T16:50:24.707 回答
13

不,那只会选择参数值。您将需要使用动态 sql。

在您的程序中,您将拥有以下内容:

DECLARE @sql nvarchar(max) = 'SELECT ' + @columnname + ' FROM Table_1';
exec sp_executesql @sql, N''
于 2012-04-10T16:47:48.523 回答
10

尝试使用动态 SQL:

create procedure sp_First @columnname varchar 
AS 
begin 
    declare @sql nvarchar(4000);
    set @sql='select ['+@columnname+'] from Table_1';
    exec sp_executesql @sql
end 
go

exec sp_First 'sname'
go
于 2012-04-10T16:50:01.337 回答
6

这是不可能的。要么使用动态 SQL(危险),要么使用巨大的 case 表达式(慢)。

于 2012-04-10T16:46:55.480 回答
2
   Create PROCEDURE USP_S_NameAvilability
     (@Value VARCHAR(50)=null,
      @TableName VARCHAR(50)=null,
      @ColumnName VARCHAR(50)=null)
        AS
        BEGIN
        DECLARE @cmd AS NVARCHAR(max)
        SET @Value = ''''+@Value+ ''''
        SET @cmd = N'SELECT * FROM ' + @TableName + ' WHERE ' +  @ColumnName + ' = ' + @Value
        EXEC(@cmd)
      END

正如我尝试了一个答案,它正在成功执行,但是在运行它时没有给出正确的输出,上面的效果很好

于 2013-03-05T06:09:58.983 回答
1

您可以传递列名,但不能在 sql statemnt 中使用它

Select @Columnname From Table

可以构建一个动态 sql 字符串并像执行它一样EXEC (@SQL)

有关更多信息,请参阅有关动态 sql 的答案。

动态 SQL 的优缺点

于 2012-04-10T16:48:13.423 回答
0

第一次运行;

CREATE PROCEDURE sp_First @columnname NVARCHAR(128)--128 = SQL Server Maximum Column Name Length
AS
BEGIN

    DECLARE @query NVARCHAR(MAX)

    SET @query = 'SELECT ' + @columnname + ' FROM Table_1'

    EXEC(@query)

END

第二轮;

EXEC sp_First 'COLUMN_Name'
于 2020-06-08T07:25:04.447 回答
0

正如 MatBailie 所提到的,这更加安全,因为它不是动态查询,并且 sql 注入的可能性较小。我添加了一种情况,您甚至希望 where 子句是动态的。XX YY 是列名

            CREATE PROCEDURE [dbo].[DASH_getTP_under_TP]
    (
    @fromColumnName varchar(10) ,
    @toColumnName varchar(10) , 
    @ID varchar(10)
    )
    as
    begin

    -- this is the column required for where clause 
    declare @colname varchar(50)
    set @colname=case @fromUserType
        when 'XX' then 'XX'
        when 'YY' then 'YY'
        end
        select SelectedColumnId  from (
       select 
            case @toColumnName 
            when 'XX' then tablename.XX
            when 'YY' then tablename.YY
            end as SelectedColumnId,
        From tablename
        where 
        (case @fromUserType 
            when 'XX' then XX
            when 'YY' then YY
        end)= ISNULL(@ID , @colname) 
    ) as tbl1 group by SelectedColumnId 

    end
于 2017-05-30T10:11:42.673 回答
-3

请试试这个。我希望它对你有用。

Create Procedure Test
(
    @Table VARCHAR(500),
    @Column VARCHAR(100),
    @Value  VARCHAR(300)
)
AS
BEGIN

DECLARE @sql nvarchar(1000)

SET @sql = 'SELECT * FROM ' + @Table + ' WHERE ' + @Column + ' = ' + @Value

--SELECT @sql
exec (@sql)

END

-----execution----

/** Exec Test Products,IsDeposit,1 **/
于 2013-01-17T10:06:16.513 回答