Я хотел бы создать более конкретное сообщение об ошибке нарушений Postgres CHECK IN.Так, например, нарушение следующего ограничения CHECK для столбца:
management_zone varchar(15) NOT NULL CHECK (management_zone IN ('Marine', 'Terrestrial') ),
должно возвращать пользовательское сообщение об ошибке, например, например: «Подсказка: проверить орфографию. Только допустимые входные данные:« Морской »,«Terrestrial '.
Лучшее из известных мне решений - это решение, использующее сообщение об ошибке в качестве имени проверочного ограничения, то есть
ADD CONSTRAINT c_managementzone_@Check_spelling._Only_allowed_inputs_are:_'Marine',_'Terrestrial' CHECK (management_zone IN ('Marine', 'Terrestrial') ),
, а затем применение функции, которая исправляетсообщение об ошибке после знака @ путем замены подчеркивания пробелом, чтобы сделать его более читабельным. Затем функция вызывается с помощью оператора try и catch.
Этот код, однако, находится в t-sql, с которым я не знаком,и я также не знаю достаточно PL / pgSQL, чтобы можно было конвертировать и реплицировать его. Поэтому я задаюсь вопросом, может ли кто-нибудь предложить, как нечто подобное можно сделать в postgres, например, с использованием функции и триггера?
Код t-sql и пояснения доступны здесь, и я скопировал и вставил его ниже: https://social.technet.microsoft.com/wiki/contents/articles/29187.t-sql-error-handling-for-check-constraints.aspx
CREATE FUNCTION dbo.ufnGetClearErrorMessage2()
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE @Msg NVARCHAR(4000) = ERROR_MESSAGE() ;
DECLARE @ErrNum INT = ERROR_NUMBER() ;
DECLARE @ClearMessage NVARCHAR(4000) ;
IF @ErrNum = 547
BEGIN
/*--how to find @ClearMessage:
SELECT @msg ,
CHARINDEX('@', @msg) ,
RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg)) ,
CHARINDEX('"', RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg))) ,
LEFT(RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg)), CHARINDEX('"', RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg))) - 1 ) ,
REPLACE(LEFT(RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg)), CHARINDEX('"', RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg))) - 1 ), '_', SPACE(1)) + '.'
*/
SELECT @ClearMessage = @Msg + CHAR(13) +
REPLACE(LEFT(RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg)), CHARINDEX('"', RIGHT(@msg, LEN(@msg) - CHARINDEX('@', @msg))) - 1 ), '_', SPACE(1)) + '.'
END
ELSE
SET @ClearMessage = @Msg ;
RETURN @ClearMessage ;
END
Попробуйте и поймайте:
BEGIN TRY
INSERT dbo.Book
( BookId, WritingDate, publishDate )
VALUES ( 1, GETDATE(), GETDATE() + 1 )
END TRY
BEGIN CATCH
DECLARE @Msg NVARCHAR(4000) = dbo.ufnGetClearErrorMessage2();
THROW 60001, @Msg, 1;
END CATCH
Любой советвысоко ценится.