Для вызова функции SQL Server использует следующий синтаксис:
SELECT dbo.GetSquare(Item) AS SquareValue
FROM Squares;
В Oracle того же можно добиться с помощью:
SELECT GetSquare(Item) AS SquareValue
FROM Squares;
Синтаксис почти такой же, за исключением того, что SQL Server требует схему (dbo.
) перед именем функции.
Можно ли написать одинаковый оператор для вызова функции для обеих СУБД в 2024 году?
Вы пробовали SELECT owner_name.GetSquare(Item) as SquareValue FROM Squares;
в Oracle? он должен работать. Если владельца функции GetSquare
зовут dbo
, вы сможете использовать точно такой же запрос.
конечно, не будет. MT0, добавление Owner_name приведет к запуску запроса, но проблема в том, что для этого требуется, чтобы схема БД имела одинаковое имя в SqlServer, что неприемлемо.
Переключение на встроенную табличную функцию, но она используется иначе, чем скалярная.
Вы, кажется, упустили мою мысль. Цель заключалась не в том, чтобы сменить пользователя SQL Server, а в том, чтобы убедиться, что имя пользователя Oracle было DBO
, чтобы оно соответствовало имени пользователя SQL Server (которое вы не можете изменить).
МТ0, спасибо за мысли. В любом случае это ограничивающий фактор, поскольку в Oracle для каждой БД может быть только один пользователь с таким же именем.
@Vy8 - Я не уверен, почему это принципиально отличается от наличия только одной схемы DBO в SQL Server. Если вы хотите подключиться как разные пользователи и вызвать эту функцию, не можете ли вы создать ее под новым пользователем DBO (схемой) и предоставить привилегии на выполнение этим вашим реальным пользователям (возможно, через роль)? Кажется, это примерно то же самое...
Алекс Пул почти ответил на это, показав дополнительные усилия, необходимые для того, чтобы справиться с этим.
А как насчет создания в SQL Server синонима для GetSquare, который ссылается на истинного владельца dbo. Learn.microsoft.com/en-us/sql/relational-databases/synonyms/…. синонимом в используемой схеме будет getSquare(Item), который затем будет использовать dbo.getsquare(Item). Синоним — это просто указатель на полный путь к функции, и на него можно ссылаться в исходной схеме без указания полный путь к объекту из-за обрабатывающего его синонима.
В Oracle, если вы используете:
SELECT owner
FROM all_objects
WHERE object_type = 'FUNCTION'
AND object_name = 'GETSQUARE';
Он сообщит вам owner
функции (вероятно, это ваш текущий пользователь).
Вы можете вызвать функцию, используя:
SELECT owner.GetSquare(Item) AS SquareValue
FROM Squares;
(Заменяя owner
настоящим именем владельца.)
Если Oracle owner
имеет имя DBO
(примечание: заглавные буквы), вы сможете использовать:
SELECT dbo.GetSquare(Item) AS SquareValue
FROM Squares;
и используйте тот же запрос в SQL Server и Oracle.
(Примечание: вашего текущего пользователя Oracle не обязательно вызывать DBO
, вам просто нужно сделать владельцем функции пользователя с именем DBO
, а затем GRANT EXECUTE ON dbo.GetSquare TO your_current_user
, и тогда вы сможете использовать ее от своего текущего пользователя.)
Альтернативно создайте пакет Oracle с именем dbo
, содержащий функцию GetSquare
:
CREATE PACKAGE dbo IS
FUNCTION GetSquare(i_item IN Squares.Item%TYPE) RETURN Squares.Item%TYPE;
END;
/
CREATE PACKAGE BODY dbo IS
FUNCTION GetSquare(i_item IN Squares.Item%TYPE) RETURN Squares.Item%TYPE
IS
BEGIN
RETURN i_item * i_item;
END GetSquare;
END dbo;
/
Тогда вы можете вызвать:
SELECT dbo.GetSquare(Item) AS SquareValue
FROM Squares;
или:
SELECT owner_name.dbo.GetSquare(Item) AS SquareValue
FROM Squares;
Спасибо, что поделились идеями. Либо в SqlServer у меня должна быть схема с именем *owner, поэтому это требует дополнительного управления и неприемлемо. или в Oracle у меня должен быть пользователь с именем DBO, что также является ограничивающим фактором наличия одного пользователя в одной БД.
@ Vy8 Добавлен альтернативный вариант: создать PACKAGE
в Oracle с именем DBO
, содержащий функцию.
MT0, это сработало как прелесть. Вы сделали мой день. ТЫВМ!
Синтаксис вашего SQL Server также будет работать в Oracle.