问题:在 GridDB 容器上插入行时出现“指定的时间戳字符串不可接受”错误 我在 Windows 11 WSL 上运行 GridDB 版本 5.5.0-40191 CE,并安装了 Ubuntu。我正在尝试使用 CLI (gs_sh) 在表中插入行。表格布局如下所示:
CREATE TABLE DimEmployee (
EmployeeKey INTEGER NOT NULL PRIMARY KEY ,
ParentEmployeeKey INTEGER NULL,
EmployeeNationalIDAlternateKey STRING NULL,
ParentEmployeeNationalIDAlternateKey STRING NULL,
SalesTerritoryKey INTEGER NULL,
FirstName STRING NOT NULL,
LastName STRING NOT NULL,
MiddleName STRING NULL,
NameStyle BOOL NOT NULL,
Title STRING NULL,
HireDate TIMESTAMP NULL,
BirthDate TIMESTAMP NULL,
LoginID STRING NULL,
EmailAddress STRING NULL,
Phone STRING NULL,
MaritalStatus STRING NULL,
EmergencyContactName STRING NULL,
EmergencyContactPhone STRING NULL,
SalariedFlag BOOL NULL,
Gender STRING NULL,
PayFrequency BYTE NULL,
BaseRate float NULL,
VacationHours SHORT NULL,
SickLeaveHours SHORT NULL,
CurrentFlag BOOL NOT NULL,
SalesPersonFlag BOOL NOT NULL,
DepartmentName STRING NULL,
StartDate TIMESTAMP NULL,
EndDate TIMESTAMP NULL,
Status STRING NULL,
EmployeePhoto BLOB NULL );
当我运行以下 SQL INSERT 语句时,收到“指定的时间戳字符串不可接受”错误。
INSERT INTO DimEmployee VALUES (6,267,'480168528',NULL,11,'Thierry','D''Hers','B',false,'Tool Designer',TIMESTAMP('2007-07-11T00:00:00.0
00Z'),TIMESTAMP('1959-02-26T00:00:00.000Z'),'motor-works\thierry0','[email protected]','168-555-0183','M','Thierry D''Hers','168-555-
0183',false,'M',2,25.00,9,24,true,false,'Tool Design',TIMESTAMP('2007-07-11T00:00:00.000Z'),NULL,'Current',NULL);
完整的错误消息如下所示:
D20332:执行 SQL 时发生意外错误。 : msg=[[305005:SQL_PROC_VALUE_SYNTAX_ERROR] 无法计算常量 表达式(原因=指定的时间戳字符串不可接受 (值=1959-02-26T00:00:00.000Z)(原因=意外的内部错误 更新时出现实用程序问题(原因=时间字段超出范围))) (sql="插入 DimEmployee 值 (6,267,'480168528',NULL,11,'蒂埃里','D''她','B',false,'工具 设计师',TIMESTAMP('2007-07-11T00:00:00.000Z'),TIMESTAMP('1959-02-26T00:00:00.000Z'),'motor-worksthierry0','[电子邮件受保护]', '168-555-0183','M','蒂埃里D''她','168-555-0183',false,'M',2,25.00,9,24,true,false,'工具 设计',TIMESTAMP('2007-07-11T00:00:00.000Z'),NULL,'当前',NULL)") (db='public') (user='admin') (appName='gs_sh') (clientId='9ee7a962-e2cd-47ed-a5b9-d0867d9389db:91') (来源={clientId=5,地址=127.0.0.1:38326}) (地址=127.0.0.1:20001,partitionId=1084)]
根据文档 GridDB_NewSQL_SQL_Reference.pdf(可在此处获取),TIMESTAMP 列会将原始值转换为从 1970 年 1 月 1 日 00:00:00 GMT 开始的毫秒数,这是一种称为 UNIX Epoch Time 的格式。因此,BirthDate 的值 1959-02-26T00:00:00.000Z 不能存储在该列中。
一种解决方法是将 BirthDate 存储为字符串列,然后在客户端将存储的值转换为日期时间。这种方法的一个缺点是,可能会存储无效日期,例如 2 月 30 日,并且数据库系统将无法捕获无效值。
另一个解决方法是将 BirthDate 存储为 64 位整数列 (LONG),其中包含自 1970 年 1 月 1 日 00:00:00 GMT 起的毫秒数。 例如,日期 ‘1959-02-26T00:00:00.000Z’ 将存储为 -342316800000.
可以在 Python 中轻松完成将日期时间值转换为 LONG 并返回:
from datetime import datetime
# Convert the string to a datetime object
input_datetime = "1959-02-26T00:00:00.000Z"
# Calculate Unix time in milliseconds
time_difference =datetime.strptime(input_datetime, "%Y-%m-%dT%H:%M:%S.%fZ") - datetime(1970, 1, 1)
unix_time_milliseconds = int(time_difference.total_seconds() * 1000)
# Output the results
print(f"Unix Epoch Time (milliseconds): {unix_time_milliseconds}"
同样,如果日期来自 SQL Server 数据库,也可以使用以下代码轻松完成到 Unix Epoch 的转换:
DECLARE @datetime DATETIME = '1959-02-26 00:00:00.000'; -- Your datetime value
-- Convert to Unix Epoch Time in milliseconds
SELECT convert (bigint, DATEDIFF(SECOND, '1970-01-01 00:00:00', @datetime)) * 1000
+ DATEPART(MILLISECOND, @datetime) AS unix_epoch_time_ms;