Snowflake 的 BCP CHAR 值

BCP CHAR value to Snowflake

我正在尝试使用 | 创建一个 BCP 文件分隔符,然后将其加载到雪花 table.

问题: 在 SQL 服务器中,有列定义为 CHAR(4) 并且具有值 "sss" 所以当我执行 BCP 时,它被填充到 4 "sss " 的长度并被加载到雪花 由于我们的报告失败,因为他们做了类似 where column="SSS" 的事情,但由于雪花中尾随 space,正确的列没有显示。

我们不想更改我们的报告。那么,BCP 是否可以处理这些列的填充或修剪?

请注意,有 24 个 table,每个都有大约 130 多列,所以我不能在每个字符列上放置 Trim 函数

如果您的 BCP 文件保留尾随 space,那么 Snowflake 也会保留它,只要该字段是 FIELD_OPTIONALLY_ENCLOSED_BY 一个 " 或 '。您可能还想制作确保在 COPY INTO 命令的格式定义中正确设置了 TRIM_SPACE 选项。

如果您的 BCP 文件没有维护 space 并且您不知道如何让它工作,您可以在 COPY INTO 命令期间强制 space 返回SELECT 中的一些字符串函数,或者您可以为您的报告创建一个视图,该视图执行相同的字符串函数集以强制 space 为您的报告工作。

这是一个已知的 "issue" 和 BCP。 "solution" 是使用 queryout 选项,这意味着您必须在每次导出时包含一个查询。但数据就是这样。

例如:https://social.msdn.microsoft.com/Forums/sqlserver/en-US/88c258fe-d1a6-4f3a-9dac-40388d04e9c7/remove-space-in-columns-on-bcp-out?forum=transactsql

但这确实是一个 Snowflake 问题,因为 Snowflake 有自己的默认 CHAR 语义。
您会在文档 String & Binary Data Types 中收到警告,但这并不能说明全部事实。

在 Oracle(显然还有 MSSQL?MySQL?)上执行的以下命令将 select aaa 行:

CREATE TABLE C AS SELECT CAST('aaa ' AS CHAR(4)) t FROM DUAL;
SELECT * FROM C WHERE t = 'aaa';

但不会在 Snowflake 上,除非您使用 COLLATION:

创建列
CREATE OR REPLACE TABLE C (t CHAR(4) COLLATE 'en_US-rtrim');
INSERT INTO C VALUES('aaa ');
SELECT * FROM C WHERE t = 'aaa';

不幸的是,你不能ALTER创建后的排序规则,这在COPY INTO <table>之后会很方便。

PS: Mike Walton 的回答更好,TRIM_SPACECOLLATE.

干净多了

So, is there a way that BCP can handle the padding or trimming of these columns?

是的,但不是通过某些开关或选项。处理此问题的正确方法是预先设置数据类型。正如有人在对您的问题的评论中提到的那样,您创建 BCP 输出的查询应该使用 VARCHAR(4) 而不是 CHAR(4)。 BCP 正在满足您的要求。他们避免空白的方法是使用 varchar。

似乎相当快 "find and replace" 针对脚本化的查询对象可以正常工作,但您最了解自己的情况。

此外,"trim" 不起作用 - 仅供参考。即使该字段的值仅为 "SSS" (如您的示例);如果 result/column 被定义为 CHAR(4) 你将得到 4 个字节的数据和第 4 位的空白,因为你只有 3 个字节的数据。 Trim 将在查询期间工作...您得到的填充“”由副本放置在那里。纠正此问题的方法是根据需要预先设置数据类型。

除非有人知道 snowflake 中的更好方法(我不熟悉它),否则唯一的其他选择是在 SQL 和 Snowflake 之间操作文件。替换“|”用 "|"... 但是... blech.