sql - 将存储过程转换为函数
问题描述
由于 Direct Query 数据连接模式,我需要使用一个函数才能通过 Power BI 使用它,Power BI 无法使用存储过程。
因此,我正在尝试从存储过程创建一个函数。
以下是我要从中创建函数的存储过程:
ALTER PROCEDURE [dbo].[SPTest]
@Anio int,
@Mes int
AS
BEGIN
DECLARE @AnioMes varchar(8),
@AnioMes6 varchar(8)
IF @Anio IS NULL
SELECT @Anio = YEAR(GETDATE()),
@Mes = MONTH(GETDATE())
SELECT
@AnioMes = (CASE WHEN @Mes = 12 THEN @Anio + 1 ELSE @Anio END * 100 +
CASE WHEN @Mes = 12 THEN 1 ELSE @Mes + 1 END) * 100 + 1
SELECT
@AnioMes6 = CONVERT(varchar(8), DATEADD(mm, -5, @AnioMes), 112)
SELECT
YEAR(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) * 100 +
MONTH(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) AS AnioMes,
DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME) AS FECHA_CREACION,
INPUTSUBJECT,
CASE
WHEN TOWTYPE = 1 THEN 'T1'
WHEN TOWTYPE = 2 THEN 'T2'
WHEN TOWTYPE = 3 THEN 'T3'
WHEN TOWTYPE = 4 THEN 'T4'
ELSE ''
END AS TOWTYPE,
[VENDNAME]
FROM
TRUCKS
WHERE
YEAR(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) >= yEAR(@AnioMes6)
AND MONTH(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) <= MONTH(@AnioMes)
AND DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME) >= '20160701'
希望有人能给我一些关于如何从这个存储过程创建函数的指导
我试图做以下事情:
CREATE FUNCTION [dbo].[SPTest]
(
@Anio int,
@Mes int,
@AnioMes varchar(8),
@AnioMes6 varchar(8)
)
RETURNS TABLE
AS
BEGIN
if @Anio is null
Select @Anio = YEAR(GETDATE()),
@Mes = MONTH(GETDATE())
Select @AnioMes = (case when @Mes=12 then @Anio+1 else @Anio end *100 + Case when @Mes=12 then 1 else @Mes+1 end)*100 + 1
Select @AnioMes6 = convert(varchar(8), DATEADD(mm, -5, @AnioMes), 112 )
SELECT year(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME))*100+month(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) as AnioMes
,DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME) as FECHA_CREACION
,INPUTSUBJECT
,Case When TOWTYPE = 1 then 'T1'
When TOWTYPE = 2 then 'T2'
When TOWTYPE = 3 then 'T3'
When TOWTYPE = 4 then 'T4'
Else ''
End as TOWTYPE
,[VENDNAME]
FROM TRUCKS
Where year(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) >= yEAR(@AnioMes6)
and month(DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME)) <= MONTH(@AnioMes)
AND DATEADD(second, DATEDIFF(second, GETUTCDATE(), GETDATE()), CREATEDDATETIME) >= '20160701'
END
RETURN
我在 BEGIN 中收到以下错误:
BEGIN 附近的语法不正确
解决方案
首先,您应该始终尝试坚持使用内联表值函数,因为它们的性能要好得多。
内联函数没有BEGIN
orEND
并且只能包含一个AS RETURN SELECT
语句。
- 注意变量是如何转换为
VALUES
子句的 - 避免对列使用函数。无需转换
CREATEDDATETIME
为时区进行比较,而是将您的参数转换为 UTC - 出于同样的原因,不要比较日期的各个部分,构建起点和终点并与之进行比较
- 不要使用字符串转换来创建日期,它很慢并且可能是不确定的。而是使用可用的适当日期函数
CREATE OR ALTER FUNCTION [dbo].[SPTest] (
@month DATETIME
)
RETURNS TABLE
AS RETURN
SELECT
v1.AnioMes
,t.CREATEDDATETIME AT TIME ZONE 'YourTimeZoneHere' as FECHA_CREACION
,t.INPUTSUBJECT
,CASE WHEN t.TOWTYPE IN (1,2,3,4)
THEN CONCAT('T', t.TOWTYPE)
ELSE '' END AS TOWTYPE
,t.[VENDNAME]
FROM (VALUES (
DATEADD(day, 1, EOMONTH(TODATETIMEOFFSET(@month, 0)))
)) v1(AnioMes)
CROSS APPLY (VALUES (
DATEADD(month, -5, v1.AnioMes)
)) v2(AnioMes6)
CROSS JOIN TRUCKS t
WHERE t.CREATEDDATETIME >= v2.AnioMes6
AND t.CREATEDDATETIME < v1.AnioMes
AND t.CREATEDDATETIME >= '20160701';
推荐阅读
- wpf - 覆盖 MaterialDesign 复选框样式
- python - 我想在主页显示客户电话号码和硬币
- python - 将列中的值提取到新列
- spyder - Spyder 调用提示遮盖了当前的编辑行
- twilio - 一些用于 Twilio 推送身份验证的 C# 示例代码
- jsf - 咆哮消息甚至在行动之前就已经显示
- docker - 对于 Harbor Registry,目录列表不适用于 Bearer Token。接收 401 未授权令牌
- java - spring mvc下载文件IOException
- python - 需要使用 Tkinter 和 Python 为 km 或 mi 创建选项
- java - 提前几分钟安排本地通知