将此内联SQL转换为存储过程

时间:2019-09-28 08:34:57

标签: c# sql-server

如何将此内联SQL转换为存储过程

SELECT     
       PM.ProjectName           
      ,[PurposeorReason]    
      ,Reg.Name    
      ,EA.Comment as Comment   
      ,[FromDate]    
      ,[VoucherID]    
      ,[TotalAmount]    
      ,ex.CreatedOn        
  FROM [TimesheetDB].[dbo].[Expense] ex    
  inner join Registration Reg on reg.RegistrationID = ex.UserID    
  inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID 
  inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID   
  inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID 
  where FromDate  between '2019-09-25' and '2019-09-29' 
  and ea.ProjectID IN (1,2,5)
  and EA.Status = 2  

我对(1,2,5)部分有疑问。我在C#中将它作为字符串“ 1、2、5”使用,并且ProjectID是整数。

我知道我做错了什么。该查询本身运行良好。

2 个答案:

答案 0 :(得分:0)

我建议使用table-valued parameter将列表/数组传递给存储过程。在C#代码中,将参数类型SqlDbType.Structured指定为参数类型。参数值可以是DataTableIEnumerable<SqlDataRecord>DbDataReader。对于此用例,我建议使用DataTable且只有一列。

CREATE TYPE dbo.TVPProjectIdList AS TABLE (
    ProjectId int NOT NULL PRIMARY KEY
);
GO

CREATE PROCEDURE dbo.Example
      @StartDate date
    , @EndDate date
    , @Status int
    , @ProjectIdList dbo.TVPProjectIdList READONLY
AS
SET NOCOUNT ON;
SELECT     
       PM.ProjectName           
      ,[PurposeorReason]    
      ,Reg.Name    
      ,EA.Comment as Comment   
      ,[FromDate]    
      ,[VoucherID]    
      ,[TotalAmount]    
      ,ex.CreatedOn        
  FROM [TimesheetDB].[dbo].[Expense] ex    
  inner join Registration Reg on reg.RegistrationID = ex.UserID    
  inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID 
  inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID   
  inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID 
  where FromDate  between @StartDate and @EndDate
  and ea.ProjectID IN (SELECT ProjectId FROM @ProjectIdList)
  and EA.Status = @Status;
GO

答案 1 :(得分:-1)

您必须在@ProjectId字符串的开头和结尾添加逗号。

c#中,如何获取开头和结尾的逗号值

string str = "1,2,5";

string replaced=str.Replace(',',',');

string concatenatdvalue=","+replaced+',';

结果=“,1、2、5”

然后可以将结果值作为@ProjectId传递到SQL Server中……

CREATE PROCEDURE dbo.sp_ProjectReport
(
    @FromDate VARCHAR(20)=NULL,
    @ToDate VARCHAR(20)=NULL,
    @ProjectId VARCHAR(50)=NULL,
    @StatusId INT=NULL
)
AS
BEGIN


SELECT     
       PM.ProjectName           
      ,[PurposeorReason]    
      ,Reg.Name    
      ,EA.Comment as Comment   
      ,[FromDate]    
      ,[VoucherID]    
      ,[TotalAmount]    
      ,ex.CreatedOn        
  FROM [TimesheetDB].[dbo].[Expense] ex    
  inner join Registration Reg on reg.RegistrationID = ex.UserID    
  inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID 
  inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID   
  inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID 
  where 
  convert(DATETIME,FromDate)   BETWEEN Convert(DATETIME,CASE WHEN isnull(@FromDate,'')='' THEN FromDate ELSE isnull(@FromDate,'') END)                     
  AND Convert(DATETIME, CASE WHEN isnull(@ToDate,'')='' THEN FromDate ELSE isnull(@ToDate,'') END)    

  and CHARINDEX(','+cast(ea.ProjectID as varchar(100))+',', @ProjectId) > 0

  and EA.Status = @StatusId 

  END 

用于执行SP的测试脚本

 EXEC dbo.sp_ProjectReport
 @FromDate='2019-09-25',
 @ToDate='2019-09-29',
 @ProjectId=',1,2,5,',
 @StatusId='2'

注意:-在这里,我还将FromDate的逻辑更改为ToDate .... null部分也是“自定义日期范围”中的“句柄”。

例如

  

如果您仅输入FromDate作为“ 07/06/2017”,那么它将给您   从结果(“ 2017年7月6日”到最后一个日期)