автоматическое приведение типов

Есть таблица с даными в которой имеется поле hash64 типа bigint
В програме (програма на Delphi) ета переменная сначала int64 потом приводится в строку и далее через Variant записывается в базу.
На MSSQL всё работало отлично, а при переходе на PostgreSQL выдает ошибку:
ERROR: column "hash64" is of type bigint but expression is of type character varying
HINT: You will need to rewrite or cast the expression.

Можно ли как нибуть отключить ету проверку типов, или же заставить автоматически приводить в нужный тип данных(не используя stored procedure для каждой таблици)? Или как нибуть обойти при помощи Rules или Triggers?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Читаем

Я прочитал

Я прочитал информацию по вашей ссилке, очень полезная информация по приведению типов, однако не смог найти ответ на свой вопрос.
Суть вопроса такова:

сторед процедура MSSQL
CREATE procedure test
@aid varchar
as
set XACT_ABORT on

INSERT INTO ct1_languages(langid, name_mlnv, code, short_code, hash64)
VALUES (3, 1, 'UuA', 'UuA', @aid)
GO
работает и без приведения типов, поле hash64 в базе типа bigint

сторед процедура PostgreSQL - работает только с прямым приведением типов
CREATE OR REPLACE FUNCTION "public"."function1" (hash64 varchar) RETURNS integer AS
$body$
BEGIN
INSERT INTO languages
VALUES (3, 1, 'UuA', 'UuA', hash64::bigint);
--запись типа VALUES (3, 1, 'UuA', 'UuA', hash64); не канает
RETURN 1;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

при помощи

при помощи правил:

CREATE TABLE "public"."foo" (
  "ID" INTEGER NOT NULL, 
  "ParentID" INTEGER, 
  "Caption" TEXT
) WITH OIDS;
 
CREATE VIEW "public"."foo_view" (
    "ID",
    "Caption",
    p_id_text)
AS
SELECT foo."ID",  foo."Caption", (foo."ParentID")::text AS p_id_text
FROM foo;
 
 
CREATE RULE "rule1" AS ON INSERT TO "public"."foo_view" 
DO INSTEAD (
INSERT INTO foo ("ID", "ParentID", "Caption") 
  VALUES (new."ID", new.p_id_text::integer, new."Caption");
);
----------------
INSERT INTO foo_view("ID",p_id_text,"Caption")
VALUES(10,'77','test');
SELECT * FROM foo WHERE "ID"=10;
 
ID	ParentID	Caption
10	77		test

хотя я не совсем понимаю, зачем в поле целого типа вставлять текст

способ конечно

способ конечно интересный, а на сколько упадёт скорость обработки запросов сервером?

> хотя я не совсем понимаю, зачем в поле целого типа вставлять текст
програма написана на Delphi5 и там используется универсальная функция для построения всех параметризованых запросов, а как список значений ей передается масив типа Array of Variant. А тип int64 не совместим з ним, поетому приходится переводить в строку.

Можете бросить

Можете бросить в меня камнем, но я считаю, что то, что автор топика кивает на MSSQL - это ещё не значит, что так лучше. Есть стандарт SQL, в котором я что-то не припомню, чтобы вместо значений одного типа можно было бы запросто подставлять значения другого типа, иначе вообще зачем нужны типы? Таким образом - хотите чтобы цифры вставлялись как строка - будьте любезны выполнить ЯВНОЕ приведение типа. Ах MSSQL работает не так? Да будьте любезны - это проблемы MSSQL, как продукта нарушающего стандарты, а никак не PostgreSQL.

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

Камнем я

Камнем я бросать не собираюсь, и не на какую либо базу даних тоже не киваю. У меня есть програма которая прекрасно работала в MSSQL, моя задача просто протестировать програму под другими базами даних, Firebird тоже пока справляется.

Ещо раз уточню свой вопрос, дабы не возникало непонятных притензий и не довольствий:
то что так нельзя делать я и сам прекрасно понимаю, но так уже ести и менять никто не будет, возможно в PostgreSQL ести какая нибуть "волшебная галочка" в настройках, которая включит одну лишнюю попытку приведения типов при использовании параметризированих запросов. Такие же проблемы возникают при вставке дати и строки длиннее 64 символов.

"волшебная

"волшебная галочка" отсутствует, но есть такая вещь http://postgresql.ru.net/manual/sql-createcast.html
не забудьте AS IMPLICIT

CREATE TABLE "public"."foo" (
  "ID" INTEGER NOT NULL, 
  "xxl" XML
) ;
 
CREATE OR REPLACE FUNCTION public.bool_to_xml (  par  BOOLEAN) RETURNS xml AS $$
SELECT ('<boolean>'||$1::text||'</boolean>')::xml;
$$ LANGUAGE 'sql'
 
CREATE CAST (BOOLEAN AS xml) WITH FUNCTION bool_to_xml(par BOOLEAN) AS IMPLICIT ;
 
INSERT INTO foo("ID",xxl) VALUES(555,true)
 
SELECT * FROM foo WHERE "ID"=555
--ID       xxl
--555    <boolean>true</boolean>

спасибо

А ещо вот такая маленькая неувязочка:
identifier must be less than 64 characters
появляется только при параметризированом запросе,
кто знает что с етим можно зделать?

давайте

давайте переведем - "Идентификатор должен быть меньше 64 символов"
что такое идентификатор - название объекта, так?
как постгрес узнал, что вы передаете ему идентификатор? - может быть ваша строка передается в двойных кавычках?

проблема

проблема оказалась не в длине строки, а в неправильном подключении драйвера, как только попробовал другой драйвер проблема сразу же пропала, читал здесь:
http://www.citforum.ru/database/postgres/windows.shtml

хотя приведение типов тоже очень пригодилось.

Я писал эту

Я писал эту статью ещё для PostgreSQL 6.3 :)
Как видите я даже не стал её переносить на этот сайт, ибо она сильно устарела.

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023