【问题标题】:SQL Server : Create Function Wrong Syntax near 'Begin'SQL Server:在“开始”附近创建函数错误的语法
【发布时间】:2021-05-19 07:04:59
【问题描述】:

我在弄清楚如何消除错误时遇到了问题。它说 Begin 语句附近有错误的语法。我想它是以前的意思,但我不知道是什么。我尝试了许多不同的函数声明,但没有让它工作。

我的表格在流程的每个步骤中都输入一行,用于多个流程。该函数应采用进程名称(单位)和时间,并应生成该进程从开始到结束的所有行。

在没有函数的情况下执行 sql 可以正常工作。

CREATE FUNCTION [GetFullCIP]
(
 @pTime DATETIME2,
 @pName NVARCHAR(50)
)
RETURNS TABLE 
AS
BEGIN
 DECLARE @cipid int
 SELECT TOP(1) @cipid=unit_id FROM [dbo].[md_units] WHERE unit=@pName

 DECLARE @stop Datetime2;
 DECLARE @start Datetime2;

--start
 SELECT TOP (1) @start=[begin_date]   FROM [dbo].[log] WHERE [operation_id]=1  AND unit_id=@cipid AND [begin_date]   <=@pTime ORDER BY [cip_id] DESC
--stop
 SELECT TOP (1) @stop=[inserted_date] FROM [dbo].[log] WHERE [operation_id]=99 AND unit_id=@cipid AND [inserted_date]>=@pTime ORDER BY [cip_id] ASC

 
 RETURN (SELECT * FROM [dbo].[log] WHERE unit_id=@cipid AND [begin_date]>=@start AND [inserted_date]<=@stop)
END
GO

我读到我应该给返回表一个名字,比如@resdata。我试过了,最后写 SET @resdata=(SELECT ...) 但这不起作用,因为它不再知道@resdata。

提前谢谢

【问题讨论】:

  • 这能回答你的问题吗? Declare variable in table valued function 即我认为 returns table 不是正确的声明类型,如果您有多个语句。
  • 就个人而言,我还是建议使用内联表值函数,而不是多行表值函数;前者的性能要好得多。
  • @underscore_d 在该链接中,它仅使用一个值。我有多个具有多个值的行。这就是为什么我试图用 SET 将它们放入@resdata 中。现在我用 SELECT INTO 尝试了它,但它仍然不知道 resdata 是什么,尽管: ...RETURNS @ resdata TABLE ( [cip_id] [int], [inserted_date] [datetime2](2), ...跨度>
  • @Lamu 我之前没有在 sql 中写过很多函数,所以这个问题可能很愚蠢,但如果它是内联的,我认为它可以在一行到一行的基础上工作。但我需要看看之前和之后的行 und 导致其间有多个。
  • 如果你想 ping 某人 @Moeren ,你必须正确拼写他们的别名。而且我不知道您所说的“逐行基础”是什么意思。

标签: sql-server syntax-error create-function


【解决方案1】:

正如我所提到的,我会使用内联表值函数。由于没有样本数据或预期结果,这是未经测试的,但它是您发布的 ml-TVF 的直译。

CREATE FUNCTION dbo.[GetFullCIP] (@pTime datetime2(7), @pName nvarchar(50))
RETURNS table
AS RETURN

    SELECT L.* --Replace this with your explicit columns
    FROM dbo.log L
         JOIN dbo.md_units MU ON L.unit_id = MU.unit_id
    WHERE MU.Unit = @pName
      AND L.begin_date >= (SELECT TOP (1) sq.begin_date
                           FROM dbo.log sq
                           WHERE sq.operation_id = 1
                             AND sq.unit_id = MU.unit_id
                             AND sq.begin_date <= @pTime
                           ORDER BY sq.cip_id DESC)
      AND L.inserted_date <= (SELECT TOP (1) sq.inserted_date
                              FROM dbo.log sq
                              WHERE sq.operation_id = 99
                                AND sq.unit_id = MU.unit_id
                                AND sq.inserted_date >= @pTime
                              ORDER BY sq.cip_id ASC)
GO

【讨论】:

  • 我想到了这个解决方案,但我不知道 sql Server 在缓存方面有多好。日志表非常大,我想尽可能避免使用相同的查询两次。
  • 什么查询两次,@Moeren?以上没有重复。
  • 抱歉,我的脑子好像在别的地方。这实际上看起来不错。谢谢,我会试试的.. 但我仍然想知道为什么另一个不起作用
  • “我想知道为什么另一个不起作用” Smor 已经在他们的comment、@Moeren 中提到了这一点。
猜你喜欢
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多