1

所以我正在做一些业务逻辑,并想运行一些类似的代码

select id from blah where foo = 1234 for update nolock

blah当相应的行被锁定时,此代码将引发 DataMapper::SQLError 。这是理想的行为;我想捕捉这个错误并用它来通知我的应用程序逻辑。但是我想重新抛出任何其他 SQL 错误,因为它们与我正在编程的情况不同,并且以相同的方式捕获它们是错误的。

返回的错误对象有一个字符串错误消息和一个数字代码 ( 50463045)。似乎在数字代码上进行比较会很棒,但我不想50463045在不了解它是如何确定的情况下将常量嵌入我的代码中。值得注意的是,Postgres 手册建议此状态的错误代码55P03,这似乎不是一回事。我不知道我可以信任多少这个幻数,以及除了实验之外如何确定它,所以我不太习惯使用它。

错误代码是如何确定的?

4

1 回答 1

0

互联网令人痛苦地无济于事,因为搜索有关 DataObjects SQL 错误的内容似乎主要返回与引发错误的其他软件有关的问题,而不是有关错误本身的信息......但是在找到正确的源代码并浏览源代码之后,我终于找到了 do_postgres.c

void do_postgres_raise_error(VALUE self, PGresult *result, VALUE query) {
  const char *message = PQresultErrorMessage(result);
  char *sql_state = PQresultErrorField(result, PG_DIAG_SQLSTATE);
  int postgres_errno = MAKE_SQLSTATE(sql_state[0], sql_state[1], sql_state[2], sql_state[3], sql_state[4]);

  PQclear(result);

  data_objects_raise_error(self, do_postgres_errors, postgres_errno, message, query, rb_str_new2(sql_state));
}

注意 5 个字符的状态是如何传递给MAKE_SQLSTATE... 的,然后也传递给data_objects_raise_error它自己。我无法追踪 MAKE_SQLSTATE 的定义位置,以找出生成这个整数的疯狂操作,但看来我可以直接使用错误对象的.sqlstate属性,并设置我的条件e.sqlstate == '55P03'

于 2012-04-24T20:55:01.333 回答