1

我被要求在我们数据库中另一个字段的日期前 1 个月填写一个日期。

这就像如果日期是1/16/13然后我会在新字段中输入12/16/12.

我遇到的问题是,在我使用的 Sybase Advantage 数据库中,某些本机 SQL 数据库的正常功能并不存在于相同的容量中。

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>
4

1 回答 1

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,DAYYEAR:

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错误等原因,整个语句没有执行)。

如果有任何不清楚的地方,您可以就您仍然遇到的具体问题发表评论或提出其他问题。

于 2013-08-28T09:54:54.163 回答