如何防止 SQL 服务器在导入数据时去除前导零

How to prevent SQL Server from stripping leading zeros when importing data

A data file 导入到 SQL Server table。数据文件中的一列是文本数据类型,该列中的值仅为整数。 SQL 服务器数据库中目标 table 中的相应列的类型为 varchar(100)。但是在数据导入之后,SQL 服务器将 0474525431 等值存储为 4.74525431E8Scientific Notations.

问题: 在上述情况下,我们如何防止SQL 服务器将值存储到Scientific Notations。例如,当 0474525431 被插入到 VARCHAR(100) 列时,它应该按原样存储而不是 4.74525431E8

更新:

导入数据的代码:

from pyspark.sql.functions import *

df = spark.read.csv(".../Test/MyFile.csv", header="true", inferSchema="true")

server_name = "jdbc:sqlserver://{SERVER_ADDR}"
database_name = "database_name"
url = server_name + ";" + "databaseName=" + database_name + ";"

table_name = "table_name"
username = "username"
password = "myPassword"

try:
  df.write \
    .format("com.microsoft.sqlserver.jdbc.spark") \
    .mode("overwrite") \
    .option("url", url) \
    .option("dbtable", table_name) \
    .option("user", username) \
    .option("password", password) \
    .save()
except ValueError as error :
    print("Connector write failed", error)

更新2:

这个问题似乎也与前导零有关。我创建了一个示例文件(如下所示)并将其数据导入相应的 SQL table(也如下所示),并注意到前导零已被删除。尽管数据文件中的所有 6 列和 table 都是文本 (varchar):

,但这种情况仍在发生

数据文件:

Col1|Col2|Col3|Col4|Col5|Col6
abc|12345|Y|0123456789|D|Test
xyz|54321|Y|0123456789|D|Test
rst|67891|Y|0123456789|D|Test
uvw|65432|Y|0123456789|D|Test

Table数据导入后

Spark 正在推断架构,它正在为包含值“0474525431”的列选择 integer。因此,当读取 DataFrame 时,该值将转换为整数并丢弃前导零。

因此您需要确保 DataFrame 具有正确的类型。您可以在创建 DataFrame 时明确指定模式,或者关闭 inferSchema 然后将选定的列转换为不同的类型,然后再加载到 SQL 服务器。两者的例子都在 .

这是一个示例,显示如果 DataFrame 使用 string 列而不是 integer 列,则会保留前导“0”。

from pyspark.sql.functions import *

jdbcUrl = "jdbc:sqlserver://{0}:{1};database={2}".format(jdbcHostname, jdbcPort, jdbcDatabase)
connectionProperties = {
  "user" : jdbcUsername,
  "password" : jdbcPassword,
  "driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}

pushdown_query = "(select '0474525431' f, * from sys.objects) emp"
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)

df.write.mode("overwrite").option("header",True).csv("datalake/temp.csv")

df = spark.read.csv("datalake/temp.csv", header="true", inferSchema="false")
df.printSchema()


table_name = "table_name"

try:
  df.write \
    .format("com.microsoft.sqlserver.jdbc.spark") \
    .mode("overwrite") \
    .option("url", jdbcUrl) \
    .option("dbtable", table_name) \
    .option("user", jdbcUsername) \
    .option("password", jdbcPassword) \
    .save()
except ValueError as error :
    print("Connector write failed", error)

df = spark.read.jdbc(url=jdbcUrl, table=table_name, properties=connectionProperties)
display(df)