在SQLServer 2012上使用动态SQL时如何将参数传递给存储过程?

时间:2018-04-19 06:31:25

标签: sql-server stored-procedures

我正在尝试根据输入参数修改数据库中的视图。 此过程将使用实体框架执行。错误 : 消息214,级别16,状态2,过程sp_executesql,第1行 程序需要参数' @ statement'类型&n; ntext / nchar / nvarchar'。

使用动态SQL创建存储过程的代码

func demoApi() {
        Alamofire.request("https://jsonplaceholder.typicode.com/posts", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

            switch(response.result) {

            case .success(_):
                guard let json = response.result.value as! [[String:Any]]? else{ return}
                print("Response \(json)")
                for item in json {

                    self.DataYouWant.append(item)

                    // if let title = item["title"] as? String {
                    //   self.titleArray.append(title)
                    // }

                }
                if !self.getAllDetail.isEmpty{
                    DispatchQueue.main.async {
                         self.tableView.reloadData()
                    }
                }
                break

            case .failure(_):
                print("Error")
                break

            }
        }

}

3 个答案:

答案 0 :(得分:0)

您的参数订单有误。

对于系统存储过程sp_executesql,SQL语句是第一个参数。然后是变量声明,最后将值传递给动态sql中使用的变量。

像这样的东西。

Alter Procedure usp_Procedure_No
 @value VARCHAR(255),
 @constraint VARCHAR(255) = NULL
AS
BEGIN
  SET NOCOUNT ON;

   Declare @Sql NVARCHAR(MAX);

  SET @Sql = N'
    If @constraint = ''Gender'' 
        BEGIN
            alter View DupView 
            as
            Select * from Personalities where Gender != @value
        END

    If @constraint = ''Place''
        BEGIN
            alter View DupView
            as
            Select * from Personalities where Place != @value
        END     

    If @constraint = ''MaritalStatus''
        BEGIN
            alter View DupView
            as
            Select * from Personalities where MaritalStatus != @value
        END     

    If @constraint = ''Age''
        BEGIN
            alter View DupView
            as
            Select * from Personalities where PersonalityAge != @value
        END     

    If @constraint = ''Nationality''
        BEGIN
            alter View DupView
            as
            Select * from Personalities where Nationality != @value
        END     

    If @constraint = NULL
        BEGIN 

            alter View DupView
            as
            Select * from Personalities where Characterstics1 != @value OR Characterstics2!= @value OR Characterstics3 != @value
        END
        '

    EXEC sp_executesql  @Sql
                      , N'@constraint VARCHAR(255) , @value VARCHAR(255)'   
                      , @value = @value
                      , @constraint = @constraint;
END

答案 1 :(得分:0)

这是“可选的一切”模式。

CREATE PROC MyProc 
   @Gender CHAR(1) = NULL, 
   @Place VARCHAR(100) = NULL, 
   @Age INT = NULL
AS
BEGIN
  SET NOCOUNT ON    

  SELECT * FROM MyTable
  WHERE (Gender = @Gender OR @Gender IS NULL) 
  AND   (Place = @Place OR @Place IS NULL) 
  AND   (Place = @Age OR @Age IS NULL) 
END

用法:

-- This returns all people who are Male
EXEC MyProc @Gender = 'M'

-- This returns all people who are 23
EXEC MyProc @Age = 'M'

-- This returns all people who are Male and 20
EXEC MyProc @Gender = 'M', @Place = NULL, @Age = 20

将值NULL(或不定义它)传递给任何参数意味着不对其进行过滤。

这是一个存储过程,而不是视图。您需要以不同的方式对视图进行调用。

这可能会受到参数嗅探问题的影响,但它比将视图动态更改为用户硬编码参数要好得多。

这是你想要做的吗?如果没有,请解释。

答案 2 :(得分:0)

我根据我的需要实现了以下任务

set nocount on;

   declare @ToDate date = dateadd(month,datediff(month,0,getdate())-1,0)

declare @year varchar(4)  = year(@ToDate)
declare @month varchar(2) = month(@ToDate)

declare @sql nvarchar(max)
    set @sql = N'
        create or alter view dbo.wTempLogs
        as
        select * from dbo.y2019
        where
            year(LogDate) = ''_year_''
            and 
            month(LogDate) = ''_month_''    '

select @sql = replace(replace(@sql,'_year_',@year),'_month_',@month)

execute sp_executesql @sql

declare @errmsg nvarchar(max)
    set @errMsg = @sql
    raiserror (@errMsg, 0,1) with nowait