Типичные функции на SQL сервере являются скалярными и возвращают одно значение. Если вам нужны строки / столбцы, вы можете использовать функцию с табличным значением.
Я не могу проверить это, поскольку вы не предоставили тестовых данных, но вы можете попробовать что-то вроде следующего:
CREATE FUNCTION dbo.FetchCustom (
@user_name NVARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN (
SELECT
jsn.ci_id, jsn.amount, jsn.user_n
FROM sysaid_user AS usr
CROSS APPLY (
SELECT *
FROM OPENJSON ( usr.user_cust_json )
WITH (
ci_id NVARCHAR(max) '$.ci_id' ,
amount NVARCHAR(max) '$.amount',
user_n NVARCHAR(max) '$.user_name'
)
) AS jsn
WHERE
usr.[USER_NAME] = @user_name
)
GO
Основной вызов c для использования функции будет выглядеть так:
SELECT * FROM dbo.FetchCustom ( 'CONSIST-SYS\alonb' );
Кроме того, что со всеми NVARCHAR(MAX)
? У вас действительно есть имя пользователя, которое требует использования MAX? Я серьезно в этом сомневаюсь. Хорошей практикой является ограничение ваших размеров до максимума, который они могут содержать (например, NVARCHAR(50)
).
ОБНОВЛЕНИЕ:
Если usr.user_cust_ json содержит другой ключ, который на самом деле является динамическим c Например: {"data": {"4251": {"ci_id": "4251", "amount": "- 50", "user_name": "AssetStorage "}," 4289 ": {" ci_id ":" 4289 "," amount ":" - 8 "," user_name ":" AssetStorage "}," 4280 ": {" ci_id ":" 4280 "," amount " : "- 1", "user_name": "AssetStorage"}}} Как можно отобразить этот ключ в этой функции? Какое изменение для этого требуется?
Чтобы включить значение ключа в ваш набор результатов, вы можете изменить TVF следующим образом:
CREATE FUNCTION dbo.FetchCustom (
@user_name NVARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN (
SELECT
jsn.[key], jsn.ci_id, jsn.amount, jsn.user_n
FROM sysaid_user AS usr
CROSS APPLY (
SELECT
[key], ci_id, amount, user_n
FROM OPENJSON ( usr.user_cust_json, '$.data' ) AS k
CROSS APPLY (
SELECT
ci_id, amount, user_n
FROM OPENJSON ( k.[value] ) WITH (
ci_id NVARCHAR(max) '$.ci_id' ,
amount NVARCHAR(max) '$.amount',
user_n NVARCHAR(max) '$.user_name'
)
) AS d
) AS jsn
WHERE
usr.[USER_NAME] = @user_name
)
GO
Если бы вы запускали в SSMS следующее, вы можно увидеть базовый набор результатов на основе предоставленного вами JSON.
DECLARE @json VARCHAR(1000) = '{"data": {"4251":{"ci_id":"4251","amount":"-50","user_name":"AssetStorage"} ,"4289":{"ci_id":"4289","amount":"-8","user_name":"AssetStorage"} ,"4280":{"ci_id":"4280","amount":"-1","user_name":"AssetStorage"}}}';
SELECT
[key], ci_id, amount, user_n
FROM OPENJSON ( @json, '$.data' ) AS k
CROSS APPLY (
SELECT
ci_id, amount, user_n
FROM OPENJSON ( k.[value] ) WITH (
ci_id NVARCHAR(max) '$.ci_id' ,
amount NVARCHAR(max) '$.amount',
user_n NVARCHAR(max) '$.user_name'
)
) AS d;
Возвращает
+------+-------+--------+--------------+
| key | ci_id | amount | user_n |
+------+-------+--------+--------------+
| 4251 | 4251 | -50 | AssetStorage |
| 4289 | 4289 | -8 | AssetStorage |
| 4280 | 4280 | -1 | AssetStorage |
+------+-------+--------+--------------+