问题
ALTER PROCEDURE [dbo].[GetValues]
@FieldName NVARCHAR(50),
@FormName NVARCHAR(50),
@PoolName NVARCHAR(50)
AS SELECT FieldValue FROM [dbo].[Values]
INNER JOIN [dbo].[Fields]
ON [dbo].[Fields].FieldID = [dbo].[Values].FieldID
INNER JOIN [dbo].[FormFields]
ON [dbo].[FormFields].FieldID = [dbo].[Fields].FieldID
INNER JOIN [dbo].[Forms]
ON [dbo].[Forms].FormID = [dbo].[FormFields].FormID
INNER JOIN [dbo].[Pools]
ON [dbo].[Pools].FormID = [dbo].[Forms].FormID
WHERE [dbo].[Fields].FieldName = @FieldName
AND [dbo].[Forms].FormName = @FormName
AND [dbo].[Pools].PoolName = @PoolName
I expected this code to filter the Values by Field, Form and Pool names. But it only filters by the Field name. What's wrong?
Forms
FormID FormName
96 FormA
98 FormB
97 FormC
Pools
PoolID FormID PoolName
29 96 PoolA1
31 98 PoolB1
30 97 PoolC1
Records
RecordID PoolID
42 29
43 29
44 29
45 31
46 31
47 31
Values
FieldID RecordID FieldValue
101 42 Yellow
101 43 Yellow
101 44 Yellow
101 45 Pink
101 46 Pink
101 47 Pink
102 42 Smith
102 43 Jones
102 44 Fletchers
103 42 Fred
103 43 Bob
103 44 Marty
For example, if I filter with "Favorite color" (FieldID=101), "FormA" (FormID=96) and "PoolA1" (PoolID=29), it shows "Yellow,Yellow,Yellow,Pink,Pink,Pink" whereas it should be "Yellow,Yellow,Yellow".
回答1:
First of all, I suggest reversing the order of your WHERE statement, the query should execute faster. Run the query in SSMS with query plans turned on and you will see this clearly.
Secondly, I think it should work, have you done a SELECT * FROM with that query to make sure its not a problem of bad data.
回答2:
As I thought, the problem was in the stored procedure itself. Everything else was fine. The JOINs were incorrectly done and that's the reason why I got erroneous results. Here's the solution:
ALTER PROCEDURE [dbo].[GetValues]
@FieldName NVARCHAR(50),
@FormName NVARCHAR(50),
@PoolName NVARCHAR(50)
AS SELECT FieldValue
FROM [dbo].[Values]
INNER JOIN [dbo].[Fields]
ON [dbo].[Fields].FieldID = [dbo].[Values].FieldID
INNER JOIN [dbo].[Records]
ON [dbo].[Records].RecordID = [dbo].[Values].RecordID
INNER JOIN [dbo].[Pools]
ON [dbo].[Pools].PoolID = [dbo].[Records].PoolID
INNER JOIN [dbo].[Forms]
ON [dbo].[Forms].FormID = [dbo].[Pools].FormID
WHERE [dbo].[Fields].FieldName = @FieldName
AND [dbo].[Forms].FormName = @FormName
AND [dbo].[Pools].PoolName = @PoolName
回答3:
There's nothing wrong with the code you've posted. So its got to be something else. (e.g. the TV remote is fine but the TV isn't plugged in)
1) Check that the code in the proc is really what you think it is with
sp_helptext 'GetValues'
2) Make sure that there's only one GetValues and you're not using one from a different user e.g. asmo.GetValues
select * from information_schema.routines where specific_name= 'GetValues'
3) If that fails take the SQL from inside the proc. Hardcode the parameter values and run it and see if it returns the results you think it should. If it doesn't post that sql to SO.
EDIT Based on your addition of the tables I tried to replicate the problem you had but the table names in the SQL and the data names aren't the same, and aren't the same in number. So I tried to synthesize the two. The following worked. I hope it helps
Create Database Test
GO
USE Test
GO
CREATE Table Forms
(FormID int,
FormName nvarchar(50))
GO
Create Table Pools
(PoolID int,
FormID int,
PoolName nvarchar(50))
GO
Create Table Records
(RecordID int,
PoolID int)
GO
Create Table [Values]
(FieldID int,
RecordID int,
FieldValue nvarchar(50))
GO
CREATE Table [Fields]
(
FieldID int,
FieldName nvarchar(100)
)
GO
CREATE Table [FormFields]
(
FieldID int,
FormID int
)
GO
INSERT INTO Forms (FormID, FormName) VALUES (96, 'FormA')
INSERT INTO Forms (FormID, FormName) VALUES (98, 'FormB')
INSERT INTO Forms (FormID, FormName) VALUES (97, 'FormC')
GO
INSERT INTO Pools (PoolID, FormID, PoolName) Values (29, 96, 'PoolA1')
INSERT INTO Pools (PoolID, FormID, PoolName) Values (31, 98, 'PoolB1')
INSERT INTO Pools (PoolID, FormID, PoolName) Values (30, 97, 'PoolC1')
GO
INSERT INTO Records (RecordID, PoolID) Values (42, 29)
INSERT INTO Records (RecordID, PoolID) Values (43, 29)
INSERT INTO Records (RecordID, PoolID) Values (44, 29)
INSERT INTO Records (RecordID, PoolID) Values (45, 31)
INSERT INTO Records (RecordID, PoolID) Values (46, 31)
INSERT INTO Records (RecordID, PoolID) Values (47, 31)
GO
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 42, 'Yellow')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 43, 'Yellow')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 44, 'Yellow')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 45, 'Pink')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 46, 'Pink')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (101, 47, 'Pink')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (102, 42, 'Smith')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (102, 43, 'Jones')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (102, 44, 'Fletchers')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (103, 44, 'Fred')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (103, 44, 'Bob')
INSERT INTO [Values] (FieldID, RecordID, FieldValue) Values (103, 44, 'Marty')
GO
INSERT INTO [Fields] (FieldID, FieldName) Values (101, 'Color')
INSERT INTO [Fields] (FieldID, FieldName) Values (102, 'Last Name')
INSERT INTO [Fields] (FieldID, FieldName) Values (103, 'First Name')
GO
INSERT INTO FormFields (FieldID, FormID) Values (101, 96)
INSERT INTO FormFields (FieldID, FormID) Values (102, 96)
INSERT INTO FormFields (FieldID, FormID) Values (103, 96)
INSERT INTO FormFields (FieldID, FormID) Values (101, 97)
INSERT INTO FormFields (FieldID, FormID) Values (102, 97)
INSERT INTO FormFields (FieldID, FormID) Values (103, 97)
INSERT INTO FormFields (FieldID, FormID) Values (101, 98)
INSERT INTO FormFields (FieldID, FormID) Values (102, 98)
INSERT INTO FormFields (FieldID, FormID) Values (103, 98)
GO
Create PROCEDURE [dbo].[GetValues]
@FieldName NVARCHAR(50),
@FormName NVARCHAR(50),
@PoolName NVARCHAR(50)
AS
SELECT
v.FieldValue
FROM
dbo.Forms f
INNER JOIN dbo.Pools p ON f.FormID = p.FormID
INNER JOIN dbo.FormFields ff on f.FormID = ff.FormID
INNER JOIN dbo.Fields fd on fd.FieldID = ff.FieldID
INNER JOIN dbo.Records r on p.PoolID = r.PoolID
INNER JOIN dbo.[Values] v on r.RecordID = v.RecordID
and ff.FieldID = v.FieldID
WHERE
fd.FieldName = @FieldName
and f.FormName = @FormName
AND p.PoolName = @PoolName
GO
dbo.getValues 'Color', 'FormA', 'PoolA1'
来源:https://stackoverflow.com/questions/3576741/combining-multiple-sql-joins