【发布时间】:2019-05-29 07:54:13
【问题描述】:
我需要能够获得将生成具有动态查询(sp_executesql)的存储过程的结果集,问题是在定义DataSource时,在这种情况下将是存储过程,它不会从DataSource 向导返回任何列作为结果。
我有另一个报告 (rdlc),具有 DataSource 的存储过程不是返回结果集的动态查询。
我正在考虑能够捕获解决变量 (@instruction) 中的 sp_executesql 的指令,然后从 TableAdapter 的查询配置向导中将其作为 Select 再次执行。
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
需要在这两种情况下获取结果集以提供 RDLC 报告中定义的DataSource。
非常感谢!
【问题讨论】:
-
尝试在查询中添加“USE DataBaseName”。服务器可以有多个数据库,并且报表管理器不知道要查询哪个数据库。 RDLC(是文本,可以用记事本打开)文件有一个带有 CommandText 的标签,您可以将命令文本放入 SSMS 中进行测试并确保它返回结果。大于号和小于号分别是html>和 <并且需要在 SSMS 中替换。
-
好!在 CommandText 标记中为我指示了以下相同的图:
/ * Local Query * / CommandText> 关于大于和小于的符号,我无法理解您的指示。 -
html 包含字符“”的元素名称到内部文本不能包含这两个字符。所以你使用的 html 的内部文本 '>'而不是大于号和'<'而不是小于号。内部文本应该是您在 cmets 中放入的内容 "/* Local Query */ 我假设有一个真正的 SELECT 语句而不仅仅是 cmets。
-
这里添加我正在使用的 SP 的完整代码,以便为我带来结果集。正如我所指出的,不便之处在于,当我将数据集添加到 rdlc 报告时,它并没有给我任何回报。
-
我会在查询中添加一个“USE”以确保它使用的是正确的数据库。我会检查日志文件以查看数据库是否报告了任何错误。我也会尝试确定是否正在调用这些程序。您可以创建一个用于调试的视图并将写入添加到视图中,这样您就可以判断程序是否运行以及代码执行了多远。
标签: c sql-server rdlc sp-executesql