Как записать набор результатов хранимой процедуры с помощью динамического выбора (sp_executesql) в отчете RDLC - PullRequest
0 голосов
/ 02 января 2019

Мне нужно иметь возможность получить набор результатов, который сгенерирует хранимую процедуру с динамическим запросом (sp_executesql), проблема в том, что при определении DataSource, который в этом случае будет хранимой процедурой , он не возвращает ни одного столбца в результате того же самого из мастера DataSource.

У меня есть другой отчет (rdlc), что хранимая процедура с источником данных не является динамическим запросом, который возвращает набор результатов.

Я думал о том, чтобы иметь возможность захватить инструкцию, которая решает sp_executesql в переменной (@instruction), а затем взять и выполнить ее снова, как Выбрать из мастера настройки запроса TableAdapter.

ALTER PROCEDURE dbo.StoredProcedureA 
    @xmlParameter XML 
AS
BEGIN
    SET NOCOUNT ON 

    DECLARE @DespachoR  VARCHAR(100),
    @DespachoRBEsta TINYINT,
    @PaisOrigenR VARCHAR(100),
    @PaisOrigenBEsta TINYINT,
    @Estampilla INTEGER,
    @DesdeFecha VARCHAR(10),
    @HastaFecha VARCHAR(10),
    @desfecha datetime,
    @hasfecha datetime,
    @strWhereRan VARCHAR(MAX),
    @strWhere VARCHAR(MAX),


    @seteos nvarchar(200),
    @instruccion nvarchar(max),
    @instruccion2 nvarchar(max),
    @texto varchar(max),
    @columna varchar(100),
    @tipodato varchar(50)


    If @xmlParametros is not null
    begin

DECLARE @xml TABLE ( identidad integer IDENTITY (1,1) not null, tipo char(1) not null, columna varchar(30) not null, campoxml varchar(1000) not null, 
    tipodato varchar(50) not null, nulo tinyint null)

INSERT @xml (columna, tipo, campoxml, tipodato, nulo)


SELECT '@DespachoR', 'E', '(/Parameters/DESPACHOR/text())[1]', 'varchar(100)', null 
UNION ALL
SELECT '@DespachoRBEsta', 'E', '(/Parameters/DESPACHORBESTA/text())[1]', 'tinyint', null 
UNION ALL
SELECT '@PaisOrigenR', 'E', '(/Parameters/PAISORIGENR/text())[1]', 'varchar(100)', null 
UNION ALL
SELECT '@PaisOrigenBEsta', 'E', '(/Parameters/PAISORIGENRBESTA/text())[1]', 'tinyint', null 
UNION ALL
SELECT '@Estampilla', 'E', '(/Parameters/ESTAMPILLA/text())[1]', 'integer', null 
UNION ALL
SELECT '@DesdeFecha', 'E', '(/Parameters/DESDEFECHA/text())[1]', 'varchar(10)', null 
UNION ALL
SELECT '@HastaFecha', 'E', '(/Parameters/HASTAFECHA/text())[1]', 'varchar(10)', null 


SELECT @seteos = 'SET ANSI_NULLS ON
        SET QUOTED_IDENTIFIER ON
        SET CONCAT_NULL_YIELDS_NULL ON
        SET ANSI_PADDING ON
        SET ANSI_WARNINGS ON
        SET ARITHABORT ON
        SET NUMERIC_ROUNDABORT OFF '
select @instruccion =null, @instruccion2 = N'@xmlParametros xml'

DECLARE INSTRUCCION INSENSITIVE CURSOR FOR
SELECT columna, "@xmlParametros.value('" + campoxml + "', '" + tipodato + "')", tipodato
FROM @xml
WHERE tipo='E'
ORDER BY identidad  

OPEN INSTRUCCION
FETCH NEXT FROM INSTRUCCION INTO @columna, @texto, @tipodato

WHILE (@@FETCH_STATUS <> -1)
 begin
    If @instruccion is not null
        SELECT @instruccion  = @instruccion + ', '

    SELECT @instruccion  = @instruccion + @columna + '=' + @texto, @instruccion2 = @instruccion2 + ', ' + @columna + ' ' + @tipodato + ' OUTPUT'

    FETCH NEXT FROM INSTRUCCION INTO @columna, @texto, @tipodato
 end

CLOSE INSTRUCCION
DEALLOCATE INSTRUCCION

SELECT @instruccion = @seteos + N'SELECT ' + @instruccion 

--end
                    --@instruccion: SETEOS
exec sp_executesql  @instruccion, @instruccion2,@xmlParametros=@xmlParametros, @DespachoR=@DespachoR OUTPUT,
                    @DespachoRBEsta=@DespachoRBEsta OUTPUT, @PaisOrigenR=@PaisOrigenR OUTPUT, @PaisOrigenBEsta=@PaisOrigenBEsta OUTPUT, @Estampilla=@Estampilla OUTPUT,
                    @DesdeFecha=@DesdeFecha OUTPUT, @HastaFecha=@HastaFecha OUTPUT

IF @DespachoR is not null
 begin
    EXEC sp_armo_rango @DespachoR, 'D.Despacho', @DespachoRBEsta, 0, @strWhereRan OUTPUT

    IF @strWhereRan is not null
        Set @strWhere = @strWhere + " AND " + rtrim(@strWhereRan)


 end

IF @PaisOrigenR is not null
begin
     EXEC sp_armo_rango @PaisOrigenR, 'D.Paisorigen', @PaisOrigenBEsta, 0, @strWhereRan OUTPUT
     IF @strWhereRan is not null
          Set  @strWhere  =  @strWhere  + " AND " + rtrim(@strWhereRan)
end

IF @Estampilla is not null
     --Esto determina que se listen los despachos que tienen la estampilla indicada, los despachos así determinados se listan completos, 
     --es decir, con todos los rangos de estampillas.
     Set @strWhere = @strWhere + ' AND 0<>(SELECT count(*) FROM Despachosestampillas De1 (nolock)
                          WHERE     De1.Despacho=D.Despacho AND 
                               De1.Hasta >=@estampilla AND De1.Desde <= @estampilla )'

IF @DesdeFecha is not null
begin
    select @desfecha=convert(datetime, @desdefecha, 103)

     Set  @strWhere  =  @strWhere  + ' AND  D.Fecha >=@desfecha'
 end

IF @HastaFecha is not NULL
    begin
    select @hasfecha=convert(datetime, @HastaFecha, 103)

     Set @strWhere = @strWhere + ' AND  D.Fecha <=@hasfecha'
 end


Set @instruccion  = N'SELECT D.Despacho, D.Fecha as FechaD, D.Aduana, D.Paisorigen as Pais, D.Garantia, 
                CASE WHEN D.TipoGarantia="E" THEN "Efectivo" 
                     WHEN D.TipoGarantia="C" THEN "Caución" 
                     WHEN D.TipoGarantia="M" THEN "Mixto" 
                     ELSE null END as Tipo, 
                D.Efectivo, D.FechaGarantia as Fecha, D.Compania, D.Poliza, D.FechavtoGarantia as Fechavto, D.Monto as Importe, 
                De.Desde, De.Hasta, convert(varchar(254), D.Observacion) as Observacion 
          FROM Despachos D (nolock)
                LEFT JOIN Despachosestampillas De (nolock) ON D.Despacho=De.Despacho
          WHERE 1=1 ' +  @strWhere + '
          ORDER BY D.Despacho, De.Desde'


          exec sp_executesql    @instruccion, N'@estampilla integer, @desfecha datetime, @hasfecha datetime', @estampilla=@estampilla, @desfecha=@desfecha, @hasfecha=@hasfecha


    end



    END

ALTER PROCEDURE dbo.StoredProcedureB    
    @xmlParametros XML
AS
BEGIN
    SET NOCOUNT ON;
    SET CONCAT_NULL_YIELDS_NULL OFF
    SET ANSI_NULLS OFF
    SET QUOTED_IDENTIFIER OFF
    SET NOCOUNT ON

    DECLARE @Sistema CHAR(1),
@Caratula tinyint,
@FormatoQRP VARCHAR(12),

@seteos NVARCHAR(200),
@instruccion NVARCHAR(max),
@instruccion2 NVARCHAR(max),
@texto VARCHAR(max),
@columna VARCHAR(100),
@tipodato VARCHAR(50)

IF @xmlParametros is not null
 BEGIN

    DECLARE @xml TABLE ( identidad integer IDENTITY (1,1) not null, tipo char(1) not null, columna varchar(30) not null, campoxml varchar(1000) not null, 
        tipodato varchar(50) not null, nulo tinyint null)

    INSERT @xml (columna, tipo, campoxml, tipodato, nulo)

    --      PARAMETRO    DIF      RUTA_DEL_NODO                         TIPO_DATO_NODO  NULO

    SELECT '@Sistema', 'E', '(/Parameters/SISTEMA)[1]', 'char(1)', null 
    UNION ALL
    SELECT '@Caratula', 'E', '(/Parameters/CARATULA)[1]', 'tinyint', null 
    UNION ALL
    SELECT '@FormatoQRP', 'E', '(/Parameters/FORMATOQRP)[1]', 'varchar(12)', null 
    --SELECT*FROM @xml

    --SETEOS SUMADOS A LA INSTRUCCION GRAL.
    SELECT @seteos = 'SET ANSI_NULLS ON
            SET QUOTED_IDENTIFIER ON
            SET CONCAT_NULL_YIELDS_NULL ON
            SET ANSI_PADDING ON
            SET ANSI_WARNINGS ON
            SET ARITHABORT ON
            SET NUMERIC_ROUNDABORT OFF '
    select @instruccion =null, @instruccion2 = N'@xmlParametros xml'

    --DECLARA CURSOR PARA RECORRER TABLA DECLARADA
    DECLARE INSTRUCCION INSENSITIVE CURSOR FOR
    SELECT columna, "@xmlParametros.value('" + campoxml + "', '" + tipodato + "')", tipodato
    FROM @xml
    WHERE tipo='E'
    ORDER BY identidad  

    OPEN INSTRUCCION
    FETCH NEXT FROM INSTRUCCION INTO @columna, @texto, @tipodato

    WHILE (@@FETCH_STATUS <> -1)
     BEGIN
        If @instruccion is not null
            SELECT @instruccion  = @instruccion + ', '

        SELECT @instruccion  = @instruccion + @columna + '=' + @texto, @instruccion2 = @instruccion2 + ', ' + @columna + ' ' + @tipodato + ' OUTPUT'

        FETCH NEXT FROM INSTRUCCION INTO @columna, @texto, @tipodato
     END

    CLOSE INSTRUCCION
    DEALLOCATE INSTRUCCION

    SELECT @instruccion = @seteos + N'SELECT ' + @instruccion 


    exec sp_executesql  @instruccion, @instruccion2,@xmlParametros=@xmlParametros,
                        @Sistema=@Sistema OUTPUT, @Caratula=@Caratula OUTPUT,
                        @FormatoQRP=@FormatoQRP OUTPUT
 END


IF @Sistema != 'C'
    SELECT CENPREFI, CODCEN, NOMBRE, ADMNEGOCIOS
    FROM dbo.CENTROSAP  (NOLOCK)
    ORDER BY CENPREFI
ELSE
    SELECT CENPREFI, CODCEN, NOMBRE
    FROM dbo.CENTROSAP  (NOLOCK)
    ORDER BY CENPREFI
END

Необходимо получить в обоих случаях набор результатов для предоставления DataSource, определенного в отчете RDLC.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Я только что сгенерировал соединение, команду sql и адаптер данных, чтобы получить набор результатов. Не могли бы вы сказать мне, если все в порядке:

SqlConnection conexionSQL = new SqlConnection("Data Source=SRVDESARROLLO7\\BASCS;Initial Catalog=BASCSREPORT;Integrated Security=True");
conexionSQL.Open();
string stringCommand = "dbo.XXX_SP_REPORTING_SERVICES_DESPACHOS";
SqlCommand comandoSQL = new SqlCommand(stringCommand, conexionSQL);
comandoSQL.CommandType = CommandType.StoredProcedure;
comandoSQL.Parameters.AddWithValue("@xmlParametros", SqlDbType.Xml).Value = parametrosXML.ToString();
SqlDataAdapter da = new SqlDataAdapter(comandoSQL.ToString(), conexionSQL);
da.SelectCommand = comandoSQL;
BASCSREPORTDataSet dataSet1 = new BASCSREPORTDataSet();
da.Fill(dataSet1, dataSet1.Tables[0].TableName);
ReportDataSource rds = new ReportDataSource("XXX_SP_REPORTING_SERVICES_DESPACHOS", dataSet1.Tables[0]);
this.reportViewer1.LocalReport.DataSources.Clear();
this.reportViewer1.LocalReport.DataSources.Add(rds);
this.reportViewer1.LocalReport.Refresh();
this.reportViewer1.RefreshReport();
0 голосов
/ 02 января 2019

Опцию WITH RESULT SETS можно использовать для определения метаданных для хранимой процедуры, когда входные параметры не возвращают результатов. Сделав это, вы определите столбцы, которые будут использоваться для результатов, и в отчете будут работать столбцы независимо от используемого параметра. Пример этого следующий. Кроме того, нужна ли подсказка NOLOCK? Это может привести к противоречивым результатам среди прочего.

EXEC YourDatabase.YourSchema.YourSP @ParameterName
WITH RESULT SETS 
(
  (
    ColumnA INT,
    ColumnB VARCHAR(100),
    ColumnC VARCHAR(100)
  )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...