我被要求在数据库的另一个字段中填写日期前一个月的字段。
如果日期为1/16/13
,我就会在12/16/12
的日期输入新字段。
我遇到的问题是,在我使用的Sybase Advantage数据库中,某些与本机SQL数据库不相同的函数不存在于相同的容量中。
例如,{p>DATEADD
无法从我迄今为止所经历的情况中获得。
所以我使用了半等效TIMESTAMPADD
函数。当我认为我已经弄明白时,我就开始收到错误,所以这里是我觉得问题的地方,但我不知道问题是什么:
INSERT INTO
Normalization
(
memotext
)
SELECT
TIMESTAMPADD(SQL_TSI_MONTH, -1, memotext)
FROM
eqanswer
WHERE
entityrole = 'MTG_PROP_FIGS'
AND fieldnum = 22
我一直收到这个错误:
ERROR IN SCRIPT: poQuery: Error 7200: AQE Error: State = S0000; NativeError = 2124; [iAnywhere Solutions][Advantage SQL Engine]Invalid operand for operator: <assignment>
答案 0 :(得分:4)
理想的解决方案是在数据库中使用TIMESTAMP
列而不是CHAR
(或MEMO
等)列。
您必须将字符字段转换为时间戳字段才能使用TIMESTAMPADD
函数。
例如,这将输出2012-12-16
:
SELECT
LEFT(CONVERT(TIMESTAMPADD(SQL_TSI_MONTH, -1, CONVERT('2013-01-16 00:00:00', SQL_TIMESTAMP)), SQL_CHAR), 10)
FROM
system.iota
如果您的日期格式不在ISO 8601
中,则必须在输入和输出中重新格式化日期字符串。
如果它包含01/16/13
(前导零),您只需使用SUBSTRING
重新格式化字符串:
DECLARE
@Input CHAR(20);
SET
@Input = '01/16/13';
SET
@Input =
'20'
+ SUBSTRING(@Input, 7, 2)
+ '-'
+ SUBSTRING(@Input, 1, 2)
+ '-'
+ SUBSTRING(@Input, 4, 2)
+ ' 00:00:00';
SELECT
LEFT(CONVERT(TIMESTAMPADD(SQL_TSI_MONTH, -1, CONVERT(@Input, SQL_TIMESTAMP)), SQL_CHAR), 10)
FROM
system.iota
如果数据库包含1/16/13
(没有前导零),则必须使用分裂字符串算法,这超出了本问题的范围。
要重新格式化输出,您可以使用MONTH
,DAY
和YEAR
:
DECLARE
@Input CHAR(20);
DECLARE
@Temp TIMESTAMP;
SET
@Input = '01/16/13';
SET
@Input =
'20'
+ SUBSTRING(@Input, 7, 2)
+ '-'
+ SUBSTRING(@Input, 1, 2)
+ '-'
+ SUBSTRING(@Input, 4, 2)
+ ' 00:00:00';
SET
@Temp = TIMESTAMPADD(SQL_TSI_MONTH, -1, CONVERT(@Input, SQL_TIMESTAMP))
;
SELECT
TRIM(CONVERT(MONTH(@Temp), SQL_CHAR)) + '/' + TRIM(CONVERT(DAY(@Temp), SQL_CHAR)) + '/' + TRIM(CONVERT(YEAR(@Temp), SQL_CHAR))
FROM
system.iota
我建议您首先弄清楚如何使用我的示例中的变量来执行此操作。然后,您可以将其与INSERT INTO .. SELECT
语句结合使用。
您应该知道任何非有效日期格式的内容都可能导致问题(由于CONVERT
错误导致整个语句无法执行等等。)
如果有任何不清楚的地方,您可以就您仍然遇到的具体问题发表评论或提出其他问题。