我正在使用一个存储过程来给我一个学校项目的取消预订,到目前为止,我有这个处理历史参数的查询,但我不想再使用它,我希望它显示所有取消的学校项目两个表试图尽可能地优化它。
@FECHAINI AS DATETIME,
@FECHAFIN AS DATETIME,
@USUARIO AS VARCHAR(MAX),
@HISTORIAL AS VARCHAR(MAX)
AS
BEGIN
BEGIN TRY
DECLARE @QUERY AS VARCHAR(MAX)
SET @QUERY = 'SELECT
CASE WHEN (garantiada = ''S'') THEN ''G'' ELSE '''' END AS garantiada,
case when STATUSDA = ''R'' then ''Reserva-Conf'' when STATUSDA = ''E'' then ''Reserva-XConf'' when STATUSDA = ''L'' then ''Reserva-L.Espera'' when STATUSDA = ''C'' then ''Cancelada'' when STATUSDA = ''X'' then ''Cancelada(L,E)'' when STATUSDA = ''O'' then ''Check-In'' when STATUSDA = ''B'' then ''Bloqueada'' when STATUSDA = ''G'' then ''Grupos'' when STATUSDA = ''D'' then ''Check-out'' when STATUSDA = ''F'' then ''Check-Out Folio'' else STATUSDA end as STATUSDA,
NUMRESDA,NOMBREDA,NUMPERDA, TARIFADA,
SUBSTRING(cveestda1,2,LEN(cveestda1)) as cveestda1,
NUMCUADA, FHAENTDA, FHASALDA,
SUBSTRING(cveestda14,2,LEN(cveestda14)) as pqte,
SUBSTRING(cveestda2,2,LEN(cveestda2)) as age,
SUBSTRING(cveestda4,2,LEN(cveestda4)) as seg,
SUBSTRING(cveestda5,2,LEN(cveestda5)) as pg,
SUBSTRING(cveestda6,2,LEN(cveestda6)) as cia,
NUMCANDA, DEPOSIDA,
DATEDIFF(DAY,FhaEntda,FhaSalda) as Noches,
FECHRESDA,PASEDA
FROM '
IF (@HISTORIAL = 'S')
SET @QUERY += 'historial'
IF (@HISTORIAL = 'N')
SET @QUERY += 'datos'
SET @QUERY += ' WHERE FECHRESDA BETWEEN '''+ CAST(@FECHAINI AS VARCHAR(MAX))+''' AND '''+CAST(@FECHAFIN AS VARCHAR(MAX))+''' '
IF (@USUARIO <> '')
SET @QUERY += 'and STATUSDA = ''C'' and PASEDA = '''+ @USUARIO +''' ORDER BY nombreda'
ELSE
SET @QUERY += 'and STATUSDA = ''C'' ORDER BY nombreda'
PRINT(@QUERY)
EXEC (@QUERY)
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ERRORMESSAGE;
END CATCH
END
这是我到目前为止所做的修改,但它不起作用,我已经使用了 union all 并且仅使用了表的 union,但它不起作用,值得一提的是,我正在使用这个 SP在水晶报告中报告。
我不确定你是否已经尝试过这个,因为没有任何你尝试过的示例代码(你确实说过你尝试过工会的something,但它“不起作用”),但正如我所言理解它,您现在只需要两个表中的数据,忽略切换表的标志。
我就是这样做的。请注意,我已经重构了动态 sql 以使用
sp_executesql
(并删除了所有选择的字段,因为它们对于当前的问题并不重要)。
我已将您的
exec
调用切换为使用 sp_executesql
与exec
相比,它有很多优点,其中最重要的是能够参数化动态sql,从而防止注入攻击的风险(注意,我下面给出的代码可以安全地免受注入攻击,但这并不会自动只需使用sp_executesql
就会发生。如果您计划使用动态sql,您应该真的了解注入攻击是如何工作的,以及如何使用quotename
,sp_executesql
和参数化之类的东西来防止它们。)
set @QUERY = concat
('
select Field
from
(
SELECT Field = ''datos''
FROM datos
where FECHRESDA BETWEEN @FECHAINI and @FECHAFIN
and STATUSDA = ''C''
', iif(@USUARIO <> '', ' and PASEDA = @USUARIO', ''), '
union
select ''historial''
from historial
where FECHRESDA BETWEEN @FECHAINI and @FECHAFIN
and STATUSDA = ''C''
', iif(@USUARIO <> '', ' and PASEDA = @USUARIO', ''), '
) a
order by nombreda'
)
exec sp_executesql
@QUERY,
N'
@FECHAINI datetime,
@FECHAFIN datetime,
@USUARIO varchar(max) -- probably shouldnt be varchar max
',
@FECHAINI,
@FECHAFIN,
@USUARIO
我在那里使用了
union
而不是union all
,因为我不确定你的数据是什么。如果两个表中可能存在相同的行,并且您不希望重复,则使用 union
将是一种可行的方法(代价是必须在结果中进行区分)。如果您知道两个表都有互斥的数据集,并且不存在您关心的重复项,您也可以使用 union all
。它更快,因为它不能确保联合操作后有一个不同的数据集。