对于我从源头转变的每一行,我都需要独特的guid.
下面是示例脚本; 代码Guid.NewGuid()总是为所有行返回相同的代码
@Person =
EXTRACT SourceId int,
AreaCode string,
AreaDetail string,
City string
FROM "/Staging/Person"
USING Extractors.Tsv(nullEscape:"#NULL#");
@rs1 =
SELECT
Guid.NewGuid() AS PersonId,
AreaCode,
AreaDetail,
City
FROM @Person;
OUTPUT @rs1
TO "/Datamart/DimUser.tsv"
USING Outputters.Tsv(quoting:false, dateTimeFormat:null);
Run Code Online (Sandbox Code Playgroud)
请注意,U型SQL是一个说明性语言,因此将快照已知的非确定性的功能,如Guid.NewGuid()或DateTime.Now每一个脚本值.
虽然你可以通过将这些函数包装到C#函数中来解决这个问题,但是这种做法是非常不鼓励的,因为你使脚本不确定,如果执行中的节点必须重试并且不重做,则可能导致脚本失败产生可重复的结果!
那你怎么能提供一个唯一的号码?
选项是:
ROW_NUMBER() OVER ()您阅读的数据.如果您已经拥有需要保证唯一性的数据,请添加作业运行时间的时间刻度,或者获取最高现有值,或者根据您的要求获得足够大的间隔.下面是一个使用时间标记加上的示例,ROW_NUBER()以确保每次运行脚本时每个行的id都是唯一的,因为如上所述,DateTime.Now每个脚本调用U-SQL将评估一次:
@data =
SELECT *
FROM (VALUES
( "John", "Doe" ),
( "Paul", "Miller" ),
( "Tracy", "Smith" ),
( "Jane", "Doe")
) AS T(firstname, lastname);
@res =
SELECT DateTime.Now.Ticks+ROW_NUMBER() OVER () AS id,
firstname, lastname
FROM @data;
OUTPUT @res
TO "/output/data.csv"
USING Outputters.Csv();
Run Code Online (Sandbox Code Playgroud)
问题的快速摘要是,您不应尝试通过依赖于生成新Guid或任何其他基于“时间”的方法的技术来分配唯一值。这样做的原因是,由于顶点重试,性能优化等原因,可能会重新计算U-SQL中的行。
在这些情况下,这些值将重新分配一个新值,并最终在运行U-SQL脚本时导致错误-因为U-SQL要求行对于输入数据是确定性的。
不用分配新的Guid,而是使用ROW_NUMBER窗口函数,该函数可以安全地向行添加新的唯一数字。一世
@result =
SELECT
*,
ROW_NUMBER() OVER () AS UID
FROM @querylog;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1144 次 |
| 最近记录: |