Как я бросаю строку к целому числу и имею 0 в случае ошибки в броске с PostgreSQL?

Глагол REST для изменения состояния - можем ли мы договориться о POST?

blockquote>

Эталонной реализацией REST является Всемирная паутина, которая была катастрофически успешной, хотя HTML (доминирующее медиа type) указана только поддержка GET и POST.

Использование POST для небезопасных операций прекрасно .

Хотя start выглядит как глагол (нарушающий REST-практики)

blockquote>

Нет - REST не заботится о написании URI. В этом и заключается суть: сервер может в любой момент изменить URI в ссылках, так как клиенты просто переходят по ссылкам.

Тем не менее, есть проблема с предложенными вами идентификаторами, которую вы можете рассмотреть

/coffeemachines/{id}
/coffeemachines/{id}/start

Что касается REST, то это различных ресурсов. Это означает, что ваша локально кэшированная копия /coffeemachines/{id} не является недействительной , когда вы POST запросите к /coffeemachines/{id}/start.

Если вы хотите воспользоваться преимуществами поддержки кэширования, которая уже встроена в независимые от домена компоненты, то вы хотите, чтобы цель POST соответствовала цели GET: /coffeemachines/{id} [ 1135]

/coffeemachines/{id}/start, в этом дизайне, не является целью POST, но вместо этого является идентификатором ресурса формы, который отправляет стартовые сообщения в /coffeemachines/{id}. Аналогично, /coffeemachines/{id}/stop идентифицирует ресурс формы, который отправляет сообщения остановки.

Представление кофемашины будет включать ссылки на эти формы, когда переходы разрешены; например, когда кофемашина выключена, то представление кофемашины, возвращенное GET, будет включать ссылку на стартовую форму, но не ссылку на форму остановки.

/coffeemachines/{id}/start и /coffeemachines/{id}/stop отличаются от ресурсов /coffeemachines/{id} и поэтому могут иметь свои собственные политики кэширования.

Конечно, не требуется , чтобы формы были отдельными ресурсами - механизм также работал бы, если бы формы были частью представления самого ресурса /coffeemachines/{id}.

Могу ли я попросить вас рассказать о POST против PATCH

blockquote>

Я обнаружил, что это наблюдение Роя Филдинга мне помогло:

[ 1142] HTTP не пытается требовать, чтобы результаты GET были безопасными. Для этого требуется, чтобы семантика операции была безопасной, и, следовательно, это ошибка реализации, а не интерфейса или пользователя этого интерфейса, если в результате произойдет что-либо, что приведет к потере свойства

blockquote>

PATCH имеет более строгую семантику, чем POST ; это означает, что клиенты (и общие компоненты) могут сделать более сильными предположения о том, что происходит.

Так в следующих примерах:

PATCH /foo HTTP/1.1
Content-Type: application/json-patch+json

POST /foo HTTP/1.1
Content-Type: application/json-patch+json

Сервер может обрабатывать эти сообщения точно таким же образом. Клиенты, которые распознают метод PATCH, распознают, что небезопасные изменения на сервере должны быть «все или ничего» («Сервер ДОЛЖЕН применять весь набор изменений атомарно ...») и могут использовать это по своему усмотрению, но с POST это дополнительное ограничение отсутствует и не может быть принято.

Спецификация PATCH отмечает:

Сравнение с POST еще сложнее, потому что POST используется в самых разных ситуациях и может охватывать операции PUT и PATCH, если сервер выбирает. Если операция не изменяет ресурс, идентифицируемый Request-URI предсказуемым образом, следует рассмотреть POST вместо PATCH или PUT.

BLOCKQUOTE>
117
задан michal.jakubeczy 23 November 2017 в 12:59
поделиться

5 ответов

Я просто боролся с подобной проблемой, но не хотел накладных расходов на функцию. Я пришел к следующему запросу:

SELECT myfield::integer FROM mytable WHERE myfield ~ E'^\\d+$';

Postgres сокращает свои условные выражения, так что вы не должны получать нецелые числа, попадающие в ваш :: integer cast. Он также обрабатывает значения NULL (они не будут соответствовать регулярному выражению).

Если вы хотите, чтобы вместо выбора использовались нули, тогда оператор CASE должен работать:

SELECT CASE WHEN myfield~E'^\\d+$' THEN myfield::integer ELSE 0 END FROM mytable;
151
ответ дан 24 November 2019 в 02:05
поделиться

Следующая функция делает

  • , используют значение по умолчанию (error_result) для не, castable результаты, например, abc или 999999999999999999999999999999999999999999
  • сохраняют null, поскольку null
  • отрезает пробелы и другой пробел во входе
  • , значения, литые как допустимые bigints, сравнены с lower_bound к, например, осуществляют положительные значения только [1 111]
CREATE OR REPLACE FUNCTION cast_to_bigint(text) 
RETURNS BIGINT AS $
DECLARE big_int_value BIGINT DEFAULT NULL;
DECLARE error_result  BIGINT DEFAULT -1;
DECLARE lower_bound   BIGINT DEFAULT 0;
BEGIN
    BEGIN
        big_int_value := CASE WHEN $1 IS NOT NULL THEN GREATEST(TRIM($1)::BIGINT, lower_bound) END;
    EXCEPTION WHEN OTHERS THEN
        big_int_value := error_result;
    END;
RETURN big_int_value;
END;
0
ответ дан 24 November 2019 в 02:05
поделиться
[11368773-

Если данные должны быть целыми числами, и вам нужны только эти значения как целые числа, почему бы вам не пройти всю милю и преобразовать столбец в целочисленную столбец?

затем Вы можете сделать это преобразование нелегальных ценностей в нули только один раз, в точке системы, в которой данные вставляются в таблицу.

При вышеуказанном преобразовании вы заставляете Postgres снова преобразовать эти значения снова и снова для каждой единицы в каждом запросе для этой таблицы - это может серьезно ухудшить производительность, если вы делаете много запросов против этого столбца в этой таблице.

0
ответ дан 24 November 2019 в 02:05
поделиться

Вы также можете создать свою собственную функцию преобразования, внутри, в которой вы могут использовать блоки исключения:

CREATE OR REPLACE FUNCTION convert_to_integer(v_input text)
RETURNS INTEGER AS $$
DECLARE v_int_value INTEGER DEFAULT NULL;
BEGIN
    BEGIN
        v_int_value := v_input::INTEGER;
    EXCEPTION WHEN OTHERS THEN
        RAISE NOTICE 'Invalid integer value: "%".  Returning NULL.', v_input;
        RETURN NULL;
    END;
RETURN v_int_value;
END;
$$ LANGUAGE plpgsql;

тестирование:

=# select convert_to_integer('1234');
 convert_to_integer 
--------------------
               1234
(1 row)

=# select convert_to_integer('');
NOTICE:  Invalid integer value: "".  Returning NULL.
 convert_to_integer 
--------------------

(1 row)

=# select convert_to_integer('chicken');
NOTICE:  Invalid integer value: "chicken".  Returning NULL.
 convert_to_integer 
--------------------

(1 row)
89
ответ дан 24 November 2019 в 02:05
поделиться

SELECT CASE WHEN myfield="". THEN 0 ELSE myfield::integer END FROM mytable

Я никогда не работал с PostgreSQL, но я проверил manual на правильность синтаксиса выражений IF в SELECT запросах.

3
ответ дан 24 November 2019 в 02:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: