1

我正在尝试执行此查询,但由于 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

有没有其他方法可以做到这一点。

4

2 回答 2

1

Azure SQL 数据仓库中的临时表与打包产品 SQL Server 或 Azure SQL 数据库的行为略有不同 - 它们存在于会话级别。因此,您所要做的就是将您的CREATE TYPE语句转换为临时表,并根据需要将输出拆分为MERGE单独的INSERT//语句。UPDATEDELETE

例子:

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
        )
...

只需加载临时表并执行存储的过程。有关临时表范围的更多详细信息,请参见此处

如果您要更改表的很大一部分,那么您应该考虑CTAS创建新表的方法,然后按照 Ron 的建议重命名它。

于 2019-03-15T13:30:01.017 回答
1

您在那里遇到了一些挑战,因为您尝试转换的大部分内容都不是在 ASDW 上做事的方式。

首先,正如您所指出的,不支持 CREATE TYPE,并且没有等效的替代方案。

接下来,代码似乎正在对表进行单次插入。这在 ASDW 上真的很糟糕,性能会很糟糕。

接下来,ASDW 还没有 MERGE 语句。那是因为 UPDATE 不是处理不断变化的数据的最佳方式。

最后,存储过程在 ASDW 上的工作方式略有不同,它们不是编译的,而是在每次调用过程时进行解释。存储过程非常适合大块的表级逻辑,但不推荐用于具有单行操作的大量调用。

我需要更多地了解用例以提出具体建议,但总的来说,您需要考虑表格而不是行。尤其要关注处理 ELT 的 CREATE TABLE AS (CTAS) 方式。

这是一个很好的链接,它显示了如何使用 CTAS 处理等效的 Merge/Upsert:

https://docs.microsoft.com/en-us/azure/sql-data-warehouse/sql-data-warehouse-develop-ctas#replace-merge-statements

正如您将看到的,它一次处理两个表,而不是一行。这意味着您需要查看调用存储过程示例的逻辑。

如果您全神贯注地在 CTAS 中做所有事情,并且分别围绕 Distribution 做所有事情,那么您就可以拥有一个高性能的数据仓库。

于 2019-03-15T10:38:27.670 回答