我们正在尝试将azure SQL迁移到spark支持的SQL,但迁移SQL视图时存在差异,列数据类型长度与spark SQL不匹配,因此我们的SAS在与azure SQL和spark SQL数据进行比较时报告错误。
请提供示例数据类型长度供您参考。
Azure SQL Spark SQL
column1 nvarchar(5) column1 string
startdate datetime2 startdate timestamp
enddate datetime2(0) enddate timestamp
根据数据类型,您可以使用String数据类型来指定String列的长度。
但是,正如您提到的,您在使用 SAS reports BI 报告工具时遇到问题,我尝试了如下所示的源数据:
来源数据:
我已经使用
spark.sql
尝试了以下方法:
maxLen = 5
colName = "column1"
spark.sql(f"""
INSERT INTO trial_01
SELECT
CASE WHEN LENGTH({colName}) > {maxLen} THEN SUBSTR({colName}, 1, {maxLen}) ELSE {colName} END as {colName},
startdate,
enddate
FROM source_table
""")
结果:
+-------+-------------------+-------------------+
|column1| startdate| enddate|
+-------+-------------------+-------------------+
| hijkl|2024-03-02 12:00:00|2024-03-03 12:00:00|
| abcde|2024-03-01 12:00:00|2024-03-02 12:00:00|
| xyz|2024-03-03 12:00:00|2024-03-04 12:00:00|
+-------+-------------------+-------------------+
定义最大长度和列名,此查询使用
CASE
语句来确定 colName
列的长度是否超过 maxLen
。如果是,则使用 SUBSTR
函数提取 maxLen
的前 colName
字符。如果不超过长度,则保留原来的colName。 AS {colName}
部分确保修改后的列保留原始列名称。
您还可以在此处的 SO 链接中查看 SCALA 中类似问题的参考。
第二种方法:
在 Databricks SQL 中,您可以使用约束强制列的特定长度。创建表后,您可以在 ALTER TABLE 语句中使用 ADD CONSTRAINT 参数。
例如,您可以创建一个包含
STRING
列的表,并添加约束以确保该列始终包含恰好 34 个字符。
以下是示例:
CREATE TABLE new_table (
iban STRING
);
ALTER TABLE new_table ADD CONSTRAINT IBAN1 CHECK (length(IBAN) = 34);
当我尝试以下操作时,它给了我一个错误:
insert into new_table (IBAN) values ('09')
InvariantViolationException: CHECK constraint iban1 (length(IBAN) = 34) violated by row with values:
- IBAN : 09
这将强制插入 iban 列中的任何值都必须恰好包含 34 个字符。
insert into new_table (IBAN) values ("1234567890123456789012345678901234")
结果: