【问题标题】:Calling User-Defined Function in select statement returning xml data在返回 xml 数据的 select 语句中调用用户定义的函数
【发布时间】:2016-05-04 14:45:41
【问题描述】:

我在 SQL Server 2012 中创建了一个返回 XML 的用户定义函数。我想在 SELECT 语句中调用该函数。这可能吗? 当我尝试这样做时,我得到了错误:

ASSIGNMENT 语句中不允许使用 FOR XML 子句。

我希望 SELECT 语句返回一组这些命名方法,这些命名方法在其逻辑中具有其他命名方法的依赖关系。 在主 CTE 中,我获得了具有依赖关系的方法的最新版本。 UDF 遍历每个方法的逻辑并返回其中调用的任何方法。所以,我想在 SELECT 语句中调用 UDF 并返回依赖方法名称的 XML。

该函数工作并返回 XML 数据。这是函数:

ALTER FUNCTION [dbo].[GetCalledMLMs] 
(
    -- Add the parameters for the function here
    @MLM_Txt nvarchar(MAX)
)
RETURNS XML
AS
BEGIN
    -- Declare the return variable here
    DECLARE @CalledMLMs XML
    Declare @MLMTbl table (pos int, endpos int, CalledMLM nvarchar(200))
    --Logic to get the data...

    Select @CalledMLMs = CalledMLM from @MLMTbl FOR XML PATH

    -- Return the result of the function
    RETURN @CalledMLMs

END

这是调用 UDF 的 CTE。

;with cte as
(
select distinct Name, max(ID) as LatestVersion
from MLM_T 
where Logic like '%:= MLM %' and Logic not like '%standard_libs := mlm%'
group by Name
)
select MLM2.Name, LatestVersion, 
dbo.GetCalledMLMs(MLM2.Logic) as CalledMLMs
from cte join MLM_T MLM2 on cte.Name = MLM2.Name 
    and cte.LatestVersion = MLM2.ID
    and MLM2.Active = 1 and MLM2.Status in (3, 4)

运行此查询时,我收到错误,即不允许在赋值语句中使用 XML。 有什么方法可以调用SELECT语句中返回XML数据类型的函数吗?

【问题讨论】:

    标签: sql-server xml user-defined-functions


    【解决方案1】:

    如果要将变量设置为一个值,则必须使用SET 和右侧的标量值。

    SELECT @SomeVariable=SomeColumn FROM SomeTable 语法不适用于 FOR XML(而且相当危险...),因为 XML 不是 SELECT 的列,而是在选择过程之后.

    你的问题在这里:

    Select @CalledMLMs = CalledMLM from @MLMTbl FOR XML PATH
    

    尝试将其更改为

    SET @CalledMLMs = (SELECT CalledMLM FROM @MLMTbl FRO XML PATH);
    

    【讨论】:

      【解决方案2】:

      我通过更改函数以返回表而不是 XML 解决了这个问题。 所以它看起来像这样:

      FUNCTION [dbo].[GetCalledMLMsTbl] 
      (
          -- Add the parameters for the function here
          @MLM_Txt nvarchar(MAX)
      )
      --RETURNS XML
      RETURNS @MLMTbl TABLE
      (
          pos int,
          endpos int,
          CalledMLM nvarchar(200)
      )
      AS
      BEGIN
        --logic here
        insert into @MLMTbl (pos, endpos, CalledMLM) Values (@startpos, @endpos, @MLM_name)
      RETURN
      END
      

      然后我在select的'from'子句中调用了函数

      ;with cte as
      (
      select distinct Name, max(ID) as LatestVersion
      from CV3MLM 
      where Logic like '%:= MLM %' and Logic not like '%standard_libs := mlm%'
          --and Name not like '%V61_CCC' 
      group by Name
      )
      select MLM2.Name, LatestVersion, C.CalledMLM 
      from cte join MLM_tbl MLM2 on cte.Name = MLM2.Name and cte.LatestVersion = MLM2.ID
          and MLM2.Active = 1 and MLM2.Status in (3, 4)
          cross apply dbo.GetCalledMLMsTbl(MLM2.Logic) C
      order by MLM2.Name, LatestVersion
      

      【讨论】:

      • 对不起,我没有意识到我只能接受检查 1 答案。我会选择你的,因为这解决了最初的问题。感谢您的来信。
      猜你喜欢
      • 1970-01-01
      • 2016-03-15
      • 2011-05-08
      • 2011-04-11
      • 2020-01-18
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 2023-01-02
      相关资源
      最近更新 更多