【发布时间】:2016-02-19 14:55:32
【问题描述】:
我正在尝试为我正在开发的程序创建搜索功能。我目前的查询检查已选择的记录状态,可以是以下任何一种:
- 有偿和无偿
- 仅付费
- 仅限未付款
- 已删除记录
然后它会执行一个选择查询,该查询会提取与这些记录状态匹配的所有记录,这是查询:
PROCEDURE [dbo].[SearchSQL]
-- Add the parameters for the stored procedure here
@logging_ref as varchar(50) = NULL,
@summit_ac_no as varchar(50) = NULL,
@contract_no as varchar(50) = NULL,
@invoice_no as varchar(50) = NULL,
@company as varchar(50) = NULL,
@paycert as varchar(50) = NULL,
@record_type as integer = NULL,
@qs as varchar(50) = NULL,
@records as int = NULL,
@state as int = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF @state = 1
Begin
SELECT TOP(@records)
-- Reference Columns - Used to identify a Record --
r.r_id AS 'ref',
grossVal AS 'gross',
payCert AS 'cert',
-- Data Columns for Display --
logRef as 'Logging Reference',
db_recTypes.recordName AS 'Record Type',
invNo as 'Invoice No.',
invDate as 'Invoice Date',
accNo as 'Summit Account No.',
db_accountNo.name as 'Company Name',
contract as 'Contract No.',
taxStatus as 'Tax Status',
netVal as 'Net Value',
vat as 'V.A.T',
grossVal as 'Gross Value',
paycert as 'Payment Certificate No.',
period as 'Period',
paydate as 'Anticipated Payment Date',
db_qs.name as 'QS record sent to',
sentDate as 'Date sent to QS',
db_sentMethod.name as 'Sent Via',
returnedDate as 'Date Returned',
r.deleted as 'Removed',
lastModified as 'Last Modified',
creationDate as 'Date Created',
db_users.name as 'Creation User',
p.date as 'Date Paid'
-- Main Table to Reference --
FROM db_records as r
-- Proceed with SQL JOINs --
JOIN db_recTypes
ON db_recTypes.recordID = r.recType
Join db_accountNo
ON db_accountNo.com_id = r.accNo
Join db_qs
On db_qs.q_id = r.sentTo
JOIN db_sentMethod
On db_sentMethod.v_id = r.sentVia
Join db_users
On db_users.u_id = r.u_id
FULL OUTER JOIN db_payments as p
ON p.r_id = r.r_id
-- Check For the following values
WHERE
(@logging_ref IS NULL OR logRef LIKE '%' + @logging_ref + '%')
AND (@summit_ac_no IS NULL OR accNo LIKE '%' + @summit_ac_no + '%')
AND (@contract_no IS NULL OR contract LIKE '%' + @contract_no + '%')
AND (@invoice_no IS NULL OR invNo LIKE '%' + @invoice_no + '%')
AND (@company IS NULL OR db_accountNo.name LIKE '%' + @company + '%')
AND (@paycert IS NULL OR payCert LIKE '%' + @paycert + '%')
AND (@record_type IS NULL OR recType = @record_type)
AND (@qs IS NULL OR db_qs.name LIKE '%' + @qs + '%')
AND r.deleted = 0
END
ELSE
Begin
IF @state = 2
BEGIN
SELECT TOP(@records)
-- Reference Columns - Used to identify a Record --
r.r_id AS 'ref',
grossVal AS 'gross',
payCert AS 'cert',
-- Data Columns for Display --
logRef as 'Logging Reference',
db_recTypes.recordName AS 'Record Type',
invNo as 'Invoice No.',
invDate as 'Invoice Date',
accNo as 'Summit Account No.',
db_accountNo.name as 'Company Name',
contract as 'Contract No.',
taxStatus as 'Tax Status',
netVal as 'Net Value',
vat as 'V.A.T',
grossVal as 'Gross Value',
paycert as 'Payment Certificate No.',
period as 'Period',
paydate as 'Anticipated Payment Date',
db_qs.name as 'QS record sent to',
sentDate as 'Date sent to QS',
db_sentMethod.name as 'Sent Via',
returnedDate as 'Date Returned',
r.deleted as 'Removed',
lastModified as 'Last Modified',
creationDate as 'Date Created',
db_users.name as 'Creation User',
p.date as 'Date Paid'
-- Main Table to Reference --
FROM db_records as r
-- Proceed with SQL JOINs --
JOIN db_recTypes
ON db_recTypes.recordID = r.recType
Join db_accountNo
ON db_accountNo.com_id = r.accNo
Join db_qs
On db_qs.q_id = r.sentTo
JOIN db_sentMethod
On db_sentMethod.v_id = r.sentVia
Join db_users
On db_users.u_id = r.u_id
FULL OUTER JOIN db_payments as p
ON p.r_id = r.r_id
-- Check For the following values
WHERE
(@logging_ref IS NULL OR logRef LIKE '%' + @logging_ref + '%')
AND (@summit_ac_no IS NULL OR accNo LIKE '%' + @summit_ac_no + '%')
AND (@contract_no IS NULL OR contract LIKE '%' + @contract_no + '%')
AND (@invoice_no IS NULL OR invNo LIKE '%' + @invoice_no + '%')
AND (@company IS NULL OR db_accountNo.name LIKE '%' + @company + '%')
AND (@paycert IS NULL OR payCert LIKE '%' + @paycert + '%')
AND (@record_type IS NULL OR recType = @record_type)
AND (@qs IS NULL OR db_qs.name LIKE '%' + @qs + '%')
AND p.date <> null
END
ELSE
BEGIN
IF @state = 3
BEGIN
SELECT TOP(@records)
-- Reference Columns - Used to identify a Record --
r.r_id AS 'ref',
grossVal AS 'gross',
payCert AS 'cert',
-- Data Columns for Display --
logRef as 'Logging Reference',
db_recTypes.recordName AS 'Record Type',
invNo as 'Invoice No.',
invDate as 'Invoice Date',
accNo as 'Summit Account No.',
db_accountNo.name as 'Company Name',
contract as 'Contract No.',
taxStatus as 'Tax Status',
netVal as 'Net Value',
vat as 'V.A.T',
grossVal as 'Gross Value',
paycert as 'Payment Certificate No.',
period as 'Period',
paydate as 'Anticipated Payment Date',
db_qs.name as 'QS record sent to',
sentDate as 'Date sent to QS',
db_sentMethod.name as 'Sent Via',
returnedDate as 'Date Returned',
r.deleted as 'Removed',
lastModified as 'Last Modified',
creationDate as 'Date Created',
db_users.name as 'Creation User',
p.date as 'Date Paid'
-- Main Table to Reference --
FROM db_records as r
-- Proceed with SQL JOINs --
JOIN db_recTypes
ON db_recTypes.recordID = r.recType
Join db_accountNo
ON db_accountNo.com_id = r.accNo
Join db_qs
On db_qs.q_id = r.sentTo
JOIN db_sentMethod
On db_sentMethod.v_id = r.sentVia
Join db_users
On db_users.u_id = r.u_id
FULL OUTER JOIN db_payments as p
ON p.r_id = r.r_id
-- Check For the following values
WHERE
(@logging_ref IS NULL OR logRef LIKE '%' + @logging_ref + '%')
AND (@summit_ac_no IS NULL OR accNo LIKE '%' + @summit_ac_no + '%')
AND (@contract_no IS NULL OR contract LIKE '%' + @contract_no + '%')
AND (@invoice_no IS NULL OR invNo LIKE '%' + @invoice_no + '%')
AND (@company IS NULL OR db_accountNo.name LIKE '%' + @company + '%')
AND (@paycert IS NULL OR payCert LIKE '%' + @paycert + '%')
AND (@record_type IS NULL OR recType = @record_type)
AND (@qs IS NULL OR db_qs.name LIKE '%' + @qs + '%')
AND p.date = null
END
ELSE
Begin
SELECT TOP(@records)
-- Reference Columns - Used to identify a Record --
r.r_id AS 'ref',
grossVal AS 'gross',
payCert AS 'cert',
-- Data Columns for Display --
logRef as 'Logging Reference',
db_recTypes.recordName AS 'Record Type',
invNo as 'Invoice No.',
invDate as 'Invoice Date',
accNo as 'Summit Account No.',
db_accountNo.name as 'Company Name',
contract as 'Contract No.',
taxStatus as 'Tax Status',
netVal as 'Net Value',
vat as 'V.A.T',
grossVal as 'Gross Value',
paycert as 'Payment Certificate No.',
period as 'Period',
paydate as 'Anticipated Payment Date',
db_qs.name as 'QS record sent to',
sentDate as 'Date sent to QS',
db_sentMethod.name as 'Sent Via',
returnedDate as 'Date Returned',
r.deleted as 'Removed',
lastModified as 'Last Modified',
creationDate as 'Date Created',
db_users.name as 'Creation User',
p.date as 'Date Paid'
-- Main Table to Reference --
FROM db_records as r
-- Proceed with SQL JOINs --
JOIN db_recTypes
ON db_recTypes.recordID = r.recType
Join db_accountNo
ON db_accountNo.com_id = r.accNo
Join db_qs
On db_qs.q_id = r.sentTo
JOIN db_sentMethod
On db_sentMethod.v_id = r.sentVia
Join db_users
On db_users.u_id = r.u_id
FULL OUTER JOIN db_payments as p
ON p.r_id = r.r_id
-- Check For the following values
WHERE
(@logging_ref IS NULL OR logRef LIKE '%' + @logging_ref + '%')
AND (@summit_ac_no IS NULL OR accNo LIKE '%' + @summit_ac_no + '%')
AND (@contract_no IS NULL OR contract LIKE '%' + @contract_no + '%')
AND (@invoice_no IS NULL OR invNo LIKE '%' + @invoice_no + '%')
AND (@company IS NULL OR db_accountNo.name LIKE '%' + @company + '%')
AND (@paycert IS NULL OR payCert LIKE '%' + @paycert + '%')
AND (@record_type IS NULL OR recType = @record_type)
AND (@qs IS NULL OR db_qs.name LIKE '%' + @qs + '%')
AND r.deleted = 1
END
END
END
END
似乎导致此问题的表是db_payments,因为这是引用记录是否已支付的表。例如(如果该记录尚未付款,则此处不存在)
db_payments 布局为:
p_id - int - Auto Increment
r_id - int - Link to db_records
date - date - date paid
如果您需要db_records 表的布局,我可以发送。
更改的查询
现在我收到以下错误:
Msg 102, Level 15, State 1, Line 52
Incorrect syntax near 'r'.
程序如下:
USE [Sub-Con-Dev]
GO
/****** Object: StoredProcedure [dbo].[SearchSQL] Script Date: 22/02/2016 09:17:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Marcus Gloria
-- Create date: 27/01/2016
-- Description: Gets Search Results
-- =============================================
ALTER PROCEDURE [dbo].[SearchSQL]
-- Add the parameters for the stored procedure here
@logging_ref as varchar(50) = NULL,
@summit_ac_no as varchar(50) = NULL,
@contract_no as varchar(50) = NULL,
@invoice_no as varchar(50) = NULL,
@company as varchar(50) = NULL,
@paycert as varchar(50) = NULL,
@record_type as integer = NULL,
@qs as varchar(50) = NULL,
@records as int = NULL,
@state as int = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(MAX) = N'
SELECT TOP(@records)
r.r_id as ref,
grossVal as gross,
payCert as cert,
p.p_id as paid,
-- Data Columns for Display --
logRef as "Logging Reference",
db_recTypes.recordName AS "Record Type",
invNo as "Invoice No.",
invDate as "Invoice Date",
accNo as "Summit Account No.",
db_accountNo.name as "Company Name",
contract as "Contract No.",
taxStatus as "Tax Status",
netVal as "Net Value",
vat as "V.A.T",
grossVal as "Gross Value",
paycert as "Payment Certificate No.",
period as "Period",
paydate as "Anticipated Payment Date",
db_qs.name as "QS record sent to",
sentDate as "Date sent to QS",
db_sentMethod.name as "Sent Via",
returnedDate as "Date Returned",
r.deleted as "Removed",
lastModified as "Last Modified",
creationDate as "Date Created",
db_users.name as "Creation User",
p.date as "Date Paid"
-- Main Table to Reference --
FROM db_records as r
-- Proceed with SQL JOINs --
JOIN db_recTypes
ON db_recTypes.recordID = r.recType
Join db_accountNo
ON db_accountNo.com_id = r.accNo
Join db_qs
On db_qs.q_id = r.sentTo
JOIN db_sentMethod
On db_sentMethod.v_id = r.sentVia
Join db_users
On db_users.u_id = r.u_id
FULL OUTER JOIN db_payments as p
ON p.r_id = r.r_id
WHERE 1 = 1 '
IF (@logging_ref IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND logRef LIKE ''%'' + @logging_ref'
IF (@summit_ac_no IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND accNo LIKE ''%'' + @summit_ac_no'
IF (@contract_no IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND contract LIKE ''%'' + @contract_no'
IF (@invoice_no IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND invNo LIKE ''%'' + @invoice_no'
IF (@company IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND db_accountNo.name LIKE ''%'' + @company'
IF (@paycert IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND payCert LIKE ''%'' + @paycert'
IF (@record_type IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND recType LIKE ''%'' + @record_type'
IF (@qs IS NOT NULL) SET @SQL = @SQL + CHAR(13) + CHAR(10) + 'AND db_qs.name LIKE ''%'' + @qs'
DECLARE @lastToken NVARCHAR(100) =
(
CASE
WHEN @state = 1 THEN 'r.deleted = 0'
WHEN @state = 2 THEN 'p.date IS NOT NULL'
WHEN @state = 3 THEN 'p.date IS NULL'
WHEN @state = 4 THEN 'r.deleted =1'
END
)
SET @SQL = @SQL + CHAR(13) + CHAR(10) + @lastToken
EXEC sp_executesql @SQL,
N'@logging_ref as varchar(50), @summit_ac_no as varchar(50) = NULL,
@contract_no as varchar(50), @invoice_no as varchar(50), @company as varchar(50),
@paycert as varchar(50), @record_type as integer, @qs as varchar(50),
@records as int, @state as int',
@records = @records,
@logging_ref = @logging_ref,
@summit_ac_no = @summit_ac_no,
@contract_no = @contract_no,
@invoice_no = @invoice_no,
@company = @company,
@paycert = @paycert,
@record_type = @record_type,
@qs = @qs,
@records = @records,
@state = @state
END
【问题讨论】:
-
您说
The table which appears to be causing this issue,但实际上并没有说this issue是什么。什么工作不正常? -
代替连接,或者在这种情况下
full outer join,尝试left join -
你把它放在一起的方式是一个性能定时炸弹。在某些时候(并且它会随机发生),性能会降低一些可怕的东西。这里有两件事会混淆查询引擎。您有一个捕获所有查询并且您有多个执行路径。好消息是这可以修复。 Gail Shaw 有一篇关于这两个主题的精彩文章。您可以在程序中将逻辑合并在一起。sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries 和 sqlinthewild.co.za/index.php/2009/09/15/…
标签: sql sql-server join stored-procedures