Можно ли передать результат хранимой процедуры другому cfstoredproc в ColdFusion?

Я хотел бы передать результат хранимой процедуры другой хранимой процедуре в ColdFusion. Если кто сможет помочь в этом.

<cfif not isDefined("getYN")>
     <cfstoredproc procedure="stored_proc" datasource="#dsn#">
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@lang" type="in" value="#this.lang#"/>
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@sqlStatement" type="in" value="#getYN#" null="#NOT len(trim(getYN))#" />            
        <cfprocresult name="getYN" resultset = "1">
     </cfstoredproc>
</cfif>

<cfstoredproc procedure="sp_test" datasource="#dsn#">
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@lang" type="in" value="#this.lang#"/>
        <cfprocparam cfsqltype="cf_sql_varchar" dbvarname="@sqlStatement" type="in" value="#getYN#" null="#NOT len(trim(getYN))#" />            
        <cfprocresult name="get" resultset = "2">
 </cfstoredproc>

Выше приведен пример кода. Во второй хранимой процедуре я передаю результат первой хранимой процедуры в dbvarname sqlStatement второй хранимой процедуры. Но переданное значение #getYN# должно быть запросом, а не результатом, потому что я использую его для предложения FROM.

Вторая хранимая процедура в SQL Server выглядит следующим образом:

ALTER PROCEDURE [dbo].[sp_test]
    @lang CHAR(5),
    @code VARCHAR(20),
    @sqlStatement NVARCHAR(MAX) = NULL
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sSQL nVARCHAR(max)

    SET @sSQL = '   SELECT col1
             FROM '+ @sqlStatement +
           ' WHERE col2 = @lang
              AND col3 = @code '

    EXECUTE SP_EXECUTESQL @sSQL, N'@lang CHAR(5),
                           @code VARCHAR(20)', @lang, @code ;

    SET NOCOUNT OFF;
END

Кроме того, приведенные выше два кода создаются из приведенного ниже кода, чтобы заменить его на cfstoredproc вместо cfquery:

<cfif NOT isDefined("request.getYN")>

        <cfquery name="request.getYN" datasource="#request.dsn.pqr#">

SELECT
    LANGUAGE_CODE                ,
    YN_CODE                ,
    YN_DESCRIPTION          
FROM
    LANGUAGE_ALTS_YN          
WHERE
    language_code IN (
        'EN','#this.lang#'
    )        
        </cfquery>
    </cfif>

    <cfquery name="get" dbtype="query">

SELECT
    yn_description        
FROM
    request.getYN        
WHERE
    language_code =
<cfqueryparam cfsqltype="cf_sql_varchar" value="#this.lang#" />         
    AND yn_code = <cfqueryparam cfsqltype="cf_sql_varchar" 
     value="#arguments.code#" />      
     </cfquery>

person S M    schedule 20.11.2018    source источник
comment
Если ваша хранимая процедура не изменяет никаких данных, можете ли вы вместо этого создать функцию SQL?   -  person James A Mohler    schedule 21.11.2018
comment
@JamesAMohler Да, но мне нужно хранить процедуру вместо функции.   -  person S M    schedule 21.11.2018
comment
@ Miguel-F Я обновил код. Спасибо   -  person S M    schedule 21.11.2018
comment
Ваш пример кода может быть в обычном формате <cfquery>. Сказав это, я бы рекомендовал выполнить <CFDump> после первого запроса, выбрать переменные и передать их следующему. Я не уверен, что должна делать хранимая процедура, чего не могут сделать более простые методы.   -  person James A Mohler    schedule 21.11.2018
comment
@JamesAMohler да, я могу сделать это с помощью ‹cfquery›, но я пытаюсь удалить cfquery и заменить сохраненной процедурой.   -  person S M    schedule 21.11.2018
comment
Это не codereview.stackexchange.com, но я надеюсь, вы в курсе, что вы пишете в два раза больше кода, и он выйдет менее безопасным. Подозреваю, что работать будет медленнее.   -  person James A Mohler    schedule 21.11.2018
comment
Согласен с тем, что это менее безопасно. sp_execsql не защитит этот конкретный запрос.   -  person SOS    schedule 21.11.2018
comment
Добавление динамического FROM к запросу может быть очень опасным. По крайней мере, я бы добавил какой-то черный список, чтобы предотвратить доступ к системным таблицам, или, что предпочтительнее, белый список, чтобы разрешить доступ только к тем таблицам, к которым вы хотите получить доступ. Или, что еще лучше, внимательно изучите разрешения пользователей для EXECUTE и SELECT. Кроме того, можете ли вы объединить две хранимые процедуры в одну sproc? Какой вкус и версия SQL?   -  person Shawn    schedule 21.11.2018
comment
@Shawn Да, я объединил два хранимых процесса в один. Я использую SQL Server 2014 сейчас. Спасибо   -  person S M    schedule 21.11.2018
comment
Хорошая сделка и удачи. Я всегда обнаруживал, что когда вы пытаетесь что-то сделать для манипулирования данными, с которыми пытаетесь работать, обычно лучше обрабатывать их со стороны базы данных, а не со стороны приложения.   -  person Shawn    schedule 22.11.2018


Ответы (1)


Второй запрос на самом деле не является запросом. Ее нельзя превратить в хранимую процедуру, поскольку она не выполняется на сервере базы данных. Другими словами, dbtype="query" не находится на сервере БД.

Кроме того, вы можете просто отфильтровать эти данные.

Было

<cfquery name="get" dbtype="query">

 SELECT yn_description        
 FROM
    request.getYN        
 WHERE
   language_code = <cfqueryparam cfsqltype="cf_sql_varchar" value="#this.lang#" />
   AND yn_code = <cfqueryparam cfsqltype="cf_sql_varchar" 
   value="#arguments.code#" />      
 </cfquery>

Должно быть

get = request.getYN.filter(function () {
   return (lang_code == this.lang && yn_code == code);
   });

Примечание: этот код во второй строке не ограничен. Это не ошибка.

Фильтры запросов см. на странице https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-mr/queryfilter.html

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

get = request.getYN.filter(function () {
   return (lang_code == this.lang && yn_code == code);
   }).yn_description;

Кстати: если поле не является большим текстом, varchar (max) или xml, обычно имеет значение, выбираете ли вы один или все

person James A Mohler    schedule 22.11.2018
comment
Большое спасибо. Это помогло мне избавиться от встроенных операторов SQL. - person S M; 26.11.2018
comment
Но как получить только значение столбца yn_description вместо получения всех значений столбца. Еще раз спасибо. - person S M; 26.11.2018