【问题标题】:Azure SQL DW External File Format treat empty strings as NULL using PolybaseAzure SQL DW 外部文件格式使用 Polybase 将空字符串视为 NULL
【发布时间】:2019-05-08 06:34:54
【问题描述】:

我正在使用外部表将数据从存储在 blob 中的 csv 加载到 Azure SQL 数据仓库中的表。 csv 使用字符串分隔符(双引号),空字符串表示为 2 个双引号 ("")。

我希望表中的空列被视为 NULL。我使用的外部文件格式设置为 USE_TYPE_DEFAULT = FALSE,但这似乎不起作用,因为空列作为空字符串导入。并且只有当列是字符串,数字列正确转换为 NULL 时才会发生这种情况。

我还导入了一个不同的 csv,它没有使用不同的外部文件格式的字符串分隔符,并且那些空列被导入为 NULL。所以看起来它与 STRING_DELIMITER 选项有关。

csv:

col1;col2;col3;col4;col5;col6
"a";"b";"c";"1";"2";"3"
"d";"";"f";"4";"";"6"

外部文件格式的代码:

CREATE EXTERNAL FILE FORMAT eff_string_del
WITH (
        FORMAT_TYPE = DELIMITEDTEXT
        ,FORMAT_OPTIONS(
            FIELD_TERMINATOR = ';'
            ,STRING_DELIMITER = '0x22'
            ,FIRST_ROW = 2
            ,USE_TYPE_DEFAULT = False)
    )

使用外部文件格式的表格代码:

CREATE EXTERNAL TABLE dbo.test (
col1 varchar(1) null
,col2 varchar(1) null
,col3 varchar(1) null
,col4 int null
,col5 int null
,col6 int null
)
WITH (
        DATA_SOURCE = [EDS]
        ,LOCATION = N'test.csv'
        ,FILE_FORMAT = eff_string_del
        ,REJECT_TYPE = VALUE
        ,REJECT_VALUE = 0
        )

查询外部表时的结果:

SELECT *
FROM [dbo].[test]

col1 col2 col3 col4        col5        col6
---- ---- ---- ----------- ----------- -----------
a    b    c    1           2           3
d         f    4           NULL        6

有人可以帮我解释发生了什么或我做错了什么吗?

【问题讨论】:

  • UPDATE test SET col2=NULL WHERE col2 = '' 是一个选项吗?我很少将文件直接插入目标表。我总是先上台然后清理/处理它。

标签: sql-server polybase


【解决方案1】:

在外部文件格式中使用USE_TYPE_DEFAULT = False。 在分隔文本文件中使用单词 NULL 存储的任何 NULL 值都将作为字符串“NULL”导入。

例如:

CREATE EXTERNAL FILE FORMAT example_file_format
WITH (FORMAT_TYPE = DELIMITEDTEXT,
      FORMAT_OPTIONS(
          FIELD_TERMINATOR = ',',
          STRING_DELIMITER = '"',
          FIRST_ROW = 2, 
          USE_TYPE_DEFAULT = False)
)

参考:https://docs.microsoft.com/en-us/sql/t-sql/statements/create-external-file-format-transact-sql?view=sql-server-2017

【讨论】:

  • 感谢您的回答,但正如您在我的原始消息中看到的那样,我已经在我的外部文件格式中使用 USE_TYPE_DEFAULT = False
  • 是的,如果你想将'NULL'文本转换为NULL值,你需要使用USE_TYPE_DEFAULT = True但是,你需要记住INT类型的空字段变成0,空字段与varchar 变为空字符串而不是 NULL。所以,你需要选择。
【解决方案2】:

您是否考虑在该字段中添加值 NULL 而不是 ""

请参阅下面我使用以下代码执行的测试:

declare @mytable table
(id int identity primary key, column1 varchar(100))

insert into @mytable (column1)  values ('test1')
insert into @mytable (column1)  values ('test2')
insert into @mytable (column1)  values (null)
insert into @mytable (column1)  values ('test3')
insert into @mytable (column1)  values (null)

select
*
from    @mytable

结果如下所示:

这对你有用吗?

【讨论】:

  • 谢谢@Birel,但这里的问题是记录是通过使用外部表而不是简单的插入语句插入 Polybase 的。
  • O 我明白了,但是在Polybase 中不能用插入更改它吗?
猜你喜欢
  • 2017-07-28
  • 2019-07-01
  • 2021-09-23
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 2016-11-28
相关资源
最近更新 更多