我正在尝试执行此查询,但是由于azure数据仓库中不支持用户定义(创建类型)类型。我想在存储过程中使用它。
CREATE TYPE DataTypeforCustomerTable AS TABLE(
PersonID int,
Name varchar(255),
LastModifytime datetime
);
GO
CREATE PROCEDURE usp_upsert_customer_table @customer_table DataTypeforCustomerTable READONLY
AS
BEGIN
MERGE customer_table AS target
USING @customer_table AS source
ON (target.PersonID = source.PersonID)
WHEN MATCHED THEN
UPDATE SET Name = source.Name,LastModifytime = source.LastModifytime
WHEN NOT MATCHED THEN
INSERT (PersonID, Name, LastModifytime)
VALUES (source.PersonID, source.Name, source.LastModifytime);
END
GO
CREATE TYPE DataTypeforProjectTable AS TABLE(
Project varchar(255),
Creationtime datetime
);
GO
CREATE PROCEDURE usp_upsert_project_table @project_table DataTypeforProjectTable READONLY
AS
BEGIN
MERGE project_table AS target
USING @project_table AS source
ON (target.Project = source.Project)
WHEN MATCHED THEN
UPDATE SET Creationtime = source.Creationtime
WHEN NOT MATCHED THEN
INSERT (Project, Creationtime)
VALUES (source.Project, source.Creationtime);
END
还有其他替代方法吗?
答案 0 :(得分:1)
您在那里遇到了一些挑战,因为您尝试转换的大部分内容都不是在ASDW上执行操作的方式。
首先,正如您所指出的,不支持CREATE TYPE,并且没有等效的替代方法。
接下来,该代码似乎是对表进行单次插入。这对于ASDW来说真的很糟糕,性能会很糟糕。
接下来,ASDW还没有MERGE语句。这是因为UPDATE并不是处理更改数据的最佳方法。
最后,存储过程在ASDW上的工作方式略有不同,它们不是编译的,而是在每次调用该过程时进行解释的。存储过程非常适合表级逻辑的大块,但不建议用于单行操作的大容量调用。
我需要更多地了解用例,以提出具体建议,但总的来说,您需要考虑表而不是行。特别要注意处理ELT的CREATE TABLE AS(CTAS)方法。
这是一个很好的链接,它显示了如何使用CTAS来处理等同于合并/ Upsert的操作:
您将看到,它一次处理两个表,而不是一行。这意味着您需要查看调用存储过程示例的逻辑。
如果您专注于在CTAS中完成所有工作,而又独立于Distribution,则您将拥有一个高性能数据仓库。
答案 1 :(得分:1)
Azure SQL数据仓库中的临时表的行为与盒装产品SQL Server或Azure SQL数据库略有不同-它们存在于会话级别。因此,您要做的就是将CREATE TYPE
语句转换为临时表,并根据需要将MERGE
拆分为单独的INSERT
/ UPDATE
/ DELETE
语句。
示例:
CREATE TABLE #DataTypeforCustomerTable (
PersonID INT,
Name VARCHAR(255),
LastModifytime DATETIME
)
WITH
(
DISTRIBUTION = HASH( PersonID ),
HEAP
)
GO
CREATE PROCEDURE usp_upsert_customer_table
AS
BEGIN
-- Add records which do not already exist
INSERT INTO customer_table ( PersonID, Name, LastModifytime )
SELECT PersonID, Name, LastModifytime
FROM #DataTypeforCustomerTable AS source
WHERE NOT EXISTS
(
SELECT *
FROM customer_table target
WHERE source.PersonID = target.PersonID
)
...
只需加载临时表并执行存储的proc。有关临时表范围的更多详细信息,请参见here。
如果要更改表的大部分,则应考虑使用CTAS
方法来创建新表,然后按照罗恩的建议将其重命名。