8

我有两个表函数,每个函数返回一列。保证一个函数返回与另一个函数相同的行数。

我想将这些值插入到一个新的两列表中。一个列将接收来自第一个 udf 的值,第二列来自第二个 udf。插入的顺序将是 udfs 返回行的顺序。

鉴于它们不共享公共密钥,我如何加入这两个 udf?我试过使用 ROW_NUMBER() 但不太明白:

INSERT INTO dbo.NewTwoColumnTable (Column1, Column2)
SELECT udf1.[value], udf2.[value]
FROM dbo.udf1() udf1
INNER JOIN dbo.udf2() udf2 ON ??? = ???
4

3 回答 3

5

这对你没有帮助,但是 SQL 不保证行顺序,除非它被明确要求,所以它们将以你期望的顺序返回的想法对于给定的集合可能是正确的,但据我了解基于集合的想法结果,从根本上不能保证正常工作。如果它与保证顺序的东西相关联,您可能希望从 UDF 返回一个键。

尽管如此,您仍可以执行以下操作:

declare @val int
set @val=1;

Select Val1,Val2 from 
(select Value as Val2, ROW_NUMBER() over (order by @val) r from udf1) a
join 
(select Value as Val2, ROW_NUMBER() over (order by @val) r from udf2) b
on a.r=b.r

该变量解决了需要按列进行排序的问题。

如果您有编辑 UDF 的权限,我认为更好的做法是已经对来自 UDF 的数据进行排序,然后您可以将其添加ident int identity(1,1)到 udf 中的输出表中,这很清楚。

这可能很重要的原因是您的服务器决定将 udf 结果分成两个数据包。如果两者的到达顺序不符合您的预期,SQL 可以按收到的顺序返回它们,这破坏了他 UDF 将按顺序返回行的假设。这可能不是问题,但如果实际系统稍后需要结果,则此处适当的编程可以防止以后出现意外错误。

于 2012-04-18T21:08:43.087 回答
3

SQL中,“udfs 返回的订单”不能保证持续存在(即使在调用之间)。

尝试这个:

WITH    q1 AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY whatever1) rn
        FROM    udf1()
        ),
        q2 AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY whatever2) rn
        FROM    udf2()
        )
INSERT
INTO    dbo.NewTwoColumnTable (Column1, Column2)
SELECT  q1.value, q2.value
FROM    q1
JOIN    q2
ON      q2.rn = q1.rn
于 2012-04-18T20:47:32.083 回答
1

WITH ORDINALITYPostgreSQL 9.4+ 可以使用后缀在 udfs 结果的末尾附加一个 INT8 列

-- set returning function WITH ORDINALITY
SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
       ls        | n
-----------------+----
pg_serial       |  1
pg_twophase     |  2
postmaster.opts |  3
pg_notify       |  4

官方文档:http ://www.postgresql.org/docs/devel/static/functions-srf.html

相关博客:http: //michael.otacoo.com/postgresql-2/postgres-9-4-feature-highlight-with-ordinality/

于 2016-02-10T09:43:31.467 回答