請問我在預存程序set一個where但這樣裡面的@AcceptDate和@AcceptDate會變成字元串沒辦法轉成datetime
where要怎麼改才能讓他正常轉換?
SQL程式碼
ALTER PROCEDURE [dbo].[GetCheckAccept]
-- Add the parameters for the stored procedure here
@CorpNo char(2),
@AcceptDate datetime,
@AcceptDate2 datetime,
@SupplierID char(5)
AS
DECLARE @statement nvarchar(4000)
DECLARE @groupby nvarchar(4000)
DECLARE @where nvarchar(4000)
SET @statement = 'SELECT cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName,pd.Qty, SUM(DBO.CvtQtyToDec(cd.RealQty)) SendQty
FROM IC_CheckAccept c
INNER JOIN IC_CheckAcceptDetail cd ON (c.CorpNo=cd.CorpNo AND c.AcceptID=cd.AcceptID)
INNER JOIN PO_Purchase p ON (cd.CorpNo=p.CorpNo AND cd.PurchaseID=p.PurchaseID)
INNER JOIN PO_PurchaseDetail pd ON (p.CorpNo=pd.CorpNo AND p.PurchaseID=pd.PurchaseID)
INNER JOIN PO_Supplier s ON (s.SupplierID=p.SupplierID)'
IF (@SupplierID IS NULL)
BEGIN
SET @where = 'WHERE c.AcceptDate>=@AcceptDate and c.AcceptDate<DATEADD ( day,1, @AcceptDate2 ) and c.CorpNo=@CorpNo'
END
ELSE
BEGIN
SET @where = 'WHERE c.AcceptDate>=@AcceptDate and c.AcceptDate<DATEADD ( day,1, @AcceptDate2 ) and c.CorpNo=@CorpNo and p.SupplierID=@SupplierID'
END
SET @groupby = ' GROUP BY cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName, pd.Qty '
SET @statement = @statement + @where + @groupby
exec (@statement)
GO
你要把動態SQL字串透過sp_executesql 丟@AcceptDate和@AcceptDate參數進去才會是日期~
參考:
https://dotblogs.com.tw/rainmaker/2015/10/01/153472
你要是不丟參數~也是可以轉成字串型態~串到字串裡面再轉時間型態~
ALTER PROCEDURE [dbo].[GetCheckAccept]
-- Add the parameters for the stored procedure here
@CorpNo char(2),
@AcceptDate datetime,
@AcceptDate2 datetime,
@SupplierID char(5)
AS
DECLARE @statement nvarchar(4000)
DECLARE @groupby nvarchar(4000)
DECLARE @where nvarchar(4000)
SET @statement = 'SELECT cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName,pd.Qty, SUM(DBO.CvtQtyToDec(cd.RealQty)) SendQty
FROM IC_CheckAccept c
INNER JOIN IC_CheckAcceptDetail cd ON (c.CorpNo=cd.CorpNo AND c.AcceptID=cd.AcceptID)
INNER JOIN PO_Purchase p ON (cd.CorpNo=p.CorpNo AND cd.PurchaseID=p.PurchaseID)
INNER JOIN PO_PurchaseDetail pd ON (p.CorpNo=pd.CorpNo AND p.PurchaseID=pd.PurchaseID)
INNER JOIN PO_Supplier s ON (s.SupplierID=p.SupplierID)'
IF (@SupplierID IS NULL)
BEGIN
SET @where = 'WHERE c.AcceptDate>=Convert(datetime,''' + Convert(varchar,@AcceptDate,120) + ''') and c.AcceptDate<DATEADD ( day,1, Convert(datetime,''' + Convert(varchar,@AcceptDate2,120) + ''') ) and c.CorpNo=@CorpNo'
END
ELSE
BEGIN
SET @where = 'WHERE c.AcceptDate>=Convert(datetime,''' + Convert(varchar,@AcceptDate,120) + ''') and c.AcceptDate<DATEADD ( day,1, Convert(datetime,''' + Convert(varchar,@AcceptDate2,120) + ''') ) and c.CorpNo=@CorpNo and p.SupplierID=@SupplierID'
END
SET @groupby = ' GROUP BY cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName, pd.Qty '
SET @statement = @statement + @where + @groupby
exec (@statement)
GO
SET @where = 'WHERE convert(datetime,c.AcceptDate)>=@AcceptDate
and convert(datetime,c.AcceptDate)<DATEADD ( day,1, @AcceptDate2 )
and c.CorpNo=@CorpNo'
或是這樣,前端程式不動,傳入的參數還是維持字串,改由接手的預存程序來做型別轉換
ALTER PROCEDURE [dbo].[GetCheckAccept]
-- Add the parameters for the stored procedure here
@CorpNo char(2),
@Date1 varchar(10),
@Date2 varchar(10),
@SupplierID char(5)
AS
DECLARE @statement nvarchar(4000)
DECLARE @groupby nvarchar(4000)
DECLARE @where nvarchar(4000)
DECLARE @AcceptDate datetime
DECLARE @AcceptDate2 datetime
set @AcceptDate=convert(datetime,@Date1)
set @AcceptDate2=convert(datetime,@Date2)
可參考組字串方式
SELECT *
INTO #ATable
FROM
(SELECT 1 AS 'ID', '2022-10-01 00:00:00.000' AS 'CreateDate' UNION
SELECT 2, '2022-11-01 00:00:00.000' UNION
SELECT 3, '2022-12-01 00:00:00.000') data
DECLARE @statement nvarchar(4000), @where nvarchar(4000);
DECLARE @AcceptDate datetime = '2022-11-01 00:00:00.000', @AcceptDate2 datetime = '2022-12-01 00:00:00.000';
SET @where = ' WHERE CreateDate>=''' + CONVERT(VARCHAR(30), @AcceptDate, 121) + ''' and CreateDate<DATEADD ( day,1, ''' + CONVERT(VARCHAR(30), @AcceptDate2, 121) + ''')';
SELECT @statement = 'SELECT * FROM #ATable' + @where
SELECT @statement
EXEC (@statement)
DROP TABLE #ATable
我會這樣寫,把資料用字串傳進去,然後再用datetime去接資料
ALTER PROCEDURE [dbo].[GetCheckAccept]
-- Add the parameters for the stored procedure here
@CorpNo char(2),
@AcceptDate datetime,
@AcceptDate2 datetime,
@SupplierID char(5)
AS
DECLARE @statement nvarchar(4000)
DECLARE @groupby nvarchar(4000)
DECLARE @where nvarchar(4000)
SET @statement = '
declare @_CorpNo char(2) = ' + @CorpNo + '
declare @_AcceptDate datetime = ' + (select convert(varchar(30), @AcceptDate)) + '
declare @_AcceptDate2 datetime = ' + (select convert(varchar(30), @AcceptDate2)) + '
declare @_SupplierID char(5) = ' + @SupplierID + '
SELECT cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName,pd.Qty, SUM(DBO.CvtQtyToDec(cd.RealQty)) SendQty
FROM IC_CheckAccept c
INNER JOIN IC_CheckAcceptDetail cd ON (c.CorpNo=cd.CorpNo AND c.AcceptID=cd.AcceptID)
INNER JOIN PO_Purchase p ON (cd.CorpNo=p.CorpNo AND cd.PurchaseID=p.PurchaseID)
INNER JOIN PO_PurchaseDetail pd ON (p.CorpNo=pd.CorpNo AND p.PurchaseID=pd.PurchaseID)
INNER JOIN PO_Supplier s ON (s.SupplierID=p.SupplierID)'
IF (@SupplierID IS NULL)
BEGIN
SET @where = 'WHERE c.AcceptDate>=@_AcceptDate and c.AcceptDate<DATEADD ( day,1, @_AcceptDate2 ) and c.CorpNo=@_CorpNo'
END
ELSE
BEGIN
SET @where = 'WHERE c.AcceptDate>=@_AcceptDate and c.AcceptDate<DATEADD ( day,1, @_AcceptDate2 ) and c.CorpNo=@_CorpNo and p.SupplierID=@_SupplierID'
END
SET @groupby = ' GROUP BY cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName, pd.Qty '
SET @statement = @statement + @where + @groupby
exec (@statement)
GO
如果只是這種單純的select語法,其實不建議使用procedure來處理,而是建立view表後,在其他地方根據需求來變換要下的查詢條件,這邊假設是在C#的API端
create view vwCheckAccept
as
SELECT cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName,pd.Qty, SUM(DBO.CvtQtyToDec(cd.RealQty)) SendQty
FROM IC_CheckAccept c
INNER JOIN IC_CheckAcceptDetail cd ON (c.CorpNo=cd.CorpNo AND c.AcceptID=cd.AcceptID)
INNER JOIN PO_Purchase p ON (cd.CorpNo=p.CorpNo AND cd.PurchaseID=p.PurchaseID)
INNER JOIN PO_PurchaseDetail pd ON (p.CorpNo=pd.CorpNo AND p.PurchaseID=pd.PurchaseID)
INNER JOIN PO_Supplier s ON (s.SupplierID=p.SupplierID)
GROUP BY cd.CorpNo, cd.PurchaseID, cd.PurchaseSeq, cd.MaterialID, p.UseKind, p.SupplierID, s.ShortName, pd.Qty
[HttpPost]
public IActionResult Login([FromBody] MyDataModel payload)
{
SqlConnection connection = new SqlConnection("my connection string");
string sql = @" select * from vwCheckAccept
WHERE c.AcceptDate>=@_AcceptDate and c.AcceptDate<DATEADD ( day,1, @_AcceptDate2 ) and c.CorpNo=@_CorpNo";
sql += string.isNullOrEmpty(payload.SupplierID)? : "" : " and p.SupplierID=@_SupplierID";
connection.Open();
var data = connection.Query(sql, new { payload.CorpNo, payload.AcceptDate, payload.AcceptDate2, payload.SupplierID });
connection.Close();
connection.Dispose();
return Ok( new { data });
}