SQL中是否有CREATE TYPE的替代方法,因为Azure SQL数据仓库中不支持CREATE TYPE

时间:2019-03-15 08:29:31

标签: azure azure-sql-database sql-data-warehouse azure-database-mysql

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

还有其他替代方法吗?

2 个答案:

答案 0 :(得分:1)

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

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

接下来,该代码似乎是对表进行单次插入。这对于ASDW来说真的很糟糕,性能会很糟糕。

接下来,ASDW还没有MERGE语句。这是因为UPDATE并不是处理更改数据的最佳方法。

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

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

这是一个很好的链接,它显示了如何使用CTAS来处理等同于合并/ Upsert的操作:

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

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

如果您专注于在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方法来创建新表,然后按照罗恩的建议将其重命名。