SQL Join Query Returning Null - sql

I've got a query that references three tables.
The tables are as follows:
FORM_FACTOR
FORM_FACTOR_ID | FORM_FACTOR_DESCRIPTION
AOF_ORDER_LINE_QUEUE
SO_LINE_NUMBER | FORM_FACTOR_ID
AOF_ORDER_PARTS
SERIAL_NUMBER | SO_LINE_NUMBER
The idea is to get the FORM_FACTOR_DESCRIPTION using the SERIAL_NUMBER of the part. I wrote a query to do that, but for whatever reason it's returning null. I could swear this query was working, but apparently there is a flaw. Help is appreciated.
The query:
DECLARE #serial VARCHAR(50)
SET #serial = 'somestring'
SELECT
ff.[FORM_FACTOR_DESCRIPTION]
FROM
[dbo].[FORM_FACTOR] AS ff
JOIN
[dbo].[AOF_ORDER_LINE_QUEUE] AS lQ ON ff.[FORM_FACTOR_ID] = lQ.[FORM_FACTOR_ID]
JOIN
[dbo].[AOF_ORDER_PARTS] AS oO ON oO.[SO_LINE_NUMBER] = lQ.[SO_LINE_NUMBER]
WHERE
oO.[SERIAL_NUMBER] = #serial

Not really a solution here. It still remains an unsolved mystery at this point.
But to look for the root cause, perhaps you could turn the joins around and use left joins?
Perhaps it's then easier to spot at what point the joins return NULL on the right side.
In the example below I messed around with COLLATION.
Just ignore and remove it, most likely it has nothing to do with it.
DECLARE #serial VARCHAR(50);
SET #serial = 'EOXH2T100008' ;
SELECT DB_NAME() as current_db, DATABASEPROPERTYEX(DB_NAME(), 'Collation') as db_collation;
--#SQL_Latin1_General_CP1_CI_AS
--SELECT Name, Description FROM fn_helpcollations() where name like '%Latin1%' ;
declare #FORM_FACTOR table (FORM_FACTOR_ID int, FORM_FACTOR_DESCRIPTION varchar(30));
insert into #FORM_FACTOR (FORM_FACTOR_ID, FORM_FACTOR_DESCRIPTION) values (1,'test 1'),(2,'test 2');
declare #AOF_ORDER_LINE_QUEUE table (ORDER_LINE_QUEUE_ID int identity(1,1), FORM_FACTOR_ID int, SO_LINE_NUMBER int);
insert into #AOF_ORDER_LINE_QUEUE (FORM_FACTOR_ID, SO_LINE_NUMBER) values (1,100),(3,100),(2,200);
declare #AOF_ORDER_PARTS table (ORDER_PARTS_ID int identity(1,1), SO_LINE_NUMBER int, SERIAL_NUMBER VARCHAR(50) COLLATE SQL_Latin1_General_CP850_BIN);
insert into #AOF_ORDER_PARTS (SO_LINE_NUMBER, SERIAL_NUMBER) values (100,'EOXH2T100008'),(200,'eOXH2T100008');
SELECT
oO.ORDER_PARTS_ID, oO.SERIAL_NUMBER, oO.SO_LINE_NUMBER,
lQ.ORDER_LINE_QUEUE_ID, lQ.FORM_FACTOR_ID,
ff.FORM_FACTOR_DESCRIPTION
FROM #AOF_ORDER_PARTS AS oO
LEFT JOIN #AOF_ORDER_LINE_QUEUE AS lQ ON lQ.[SO_LINE_NUMBER] = oO.[SO_LINE_NUMBER]
LEFT JOIN #FORM_FACTOR AS ff ON ff.[FORM_FACTOR_ID] = lQ.[FORM_FACTOR_ID]
WHERE oO.[SERIAL_NUMBER] = #serial;

Related

Stored Procedure: Keep Query Result (as Table) in variable

I'm from Entity Framework background and I don't do much pure SQL development.
However, when dealing with EF we can do:
var persons = from x in db.Person
where x.Name.Equals("Something")
select x;
or
IQuerable<Person> persons = from x in db.Person
where x.Name.Equals("Something")
select x;
But when dealing with stored procedures, how could this be done exactly, like for example I can capture a variable by declaring DECLARE #Name NVARCHAR(15), but how to get the returned table result?
Create a table variable and insert your data into that:
DECLARE #Person table(
FirstName nvarchar(15),
LastName nvarchar(15)
);
Insert Into #Person(FirstName, LastName)
Select Firstname, LastName
From Person
Where LastName = #LastName; -- where #lastname comes from a sp parameter.
Now do stuff like
Select count(*) from #Person;
simply declare a table variable:
DECLARE #TableVariable TABLE
(
PrimaryKey INT,
Name NVARCHAR(MAX)
)
and insert the results into this table.
One way as answered by #ps2goat. And if you want Stored Procedure output into table then you can do like this :-
DECLARE #Person table
(
Id Int Identity(1,1)
,FirstName nvarchar(15)
,LastName nvarchar(15)
);
Insert Into #Person(FirstName,LastName)
Exec dbo.USP_SomeStoredProcedure <sp's parameters>;
Select Top 1
FirstName
,LastName
From #Person As p
Order By p.Id Asc
Note:- your calling procedure output and table column exactly match should be same
Well I found the right answer myself. I think I have to use cursors and that is the best to do so.

SQL Find and Insert

I have name of client and name of doctor. I want to get there ID from DB and insert IDs into table.
CREATE PROCEDURE AddMedicalCard
#Client nchar,
#Doctor nchar
AS
BEGIN
SELECT Clients.[ClientCode] AS [Code]
Into #NewClientCode
FROM Clients
WHERE Clients.[ClientName]=#Client
SELECT Personal.[DoctorCode] AS [Code]
Into #NewDoctorCode
FROM Personal
WHERE Personal.[DoctorName]=#Doctor
INSERT INTO MedicalCard
VALUES (#NewClientCode.[Code].First, #NewDoctorCode.[Code].First)
DROP TABLE #NewClientCode
DROP TABLE #NewDoctorCode
END
GO
Errors:
The multi-part identifier "#NewDoctorCode.Code.First" could not be bound.
The multi-part identifier "#NewClientCode.Code.First" could not be bound.
Column name or number of supplied values does not match table definition.
MedicalCard table design:
RecordingCode(Key), ClientCode, DoctorCode
and 5 other nullable columns.
Error message says it all. There is no such thing as #NewDoctorCode.Code.First. Your job can be easily & cleanly done as follows.
Note: It is not very correct to get clientcode and doctorcode by their names as there could be more than 1 client & doctors with the same name.
--declare two variables
declare #clientCode varchar(50), #doctorCode varchar(50)
--assign clientCode
SELECT TOP 1 #clientCode = Clients.[ClientCode]
FROM Clients
WHERE Clients.[ClientName]=#Client
--assign doctorCode
SELECT TOP 1 #doctorCode = Personal.[DoctorCode]
FROM Personal
WHERE Personal.[DoctorName]=#Doctor
--finally insert them to MedicalCard table
INSERT INTO MedicalCard (clientCodeColumn,doctorCodeColumn) --Column Names
VALUES (#clientCode,#doctorCode)
Do something like this
DECLARE #i INT;
SELECT #i = id FROM youtable;
BEGIN
Insert into tablename(column1) values(#i)
END
Try this, you should use variables and not table. If you use table then you should use insert into table select col
DECLARE #NewClientCode int
DECLARE #NewDoctorCode int
SELECT #NewClientCode = Clients.[ClientCode]
FROM Clients
WHERE Clients.[ClientName]=#Client
SELECT #NewDoctorCode = Personal.[DoctorCode]
FROM Personal
WHERE Personal.[DoctorName]=#Doctor
INSERT INTO MedicalCard
VALUES (#NewClientCode, #NewDoctorCode)
Try to use this SP:
CREATE PROCEDURE AddMedicalCard
#Client nchar,
#Doctor nchar
AS
BEGIN
INSERT INTO MedicalCard
VALUES (
SELECT TOP 1 Clients.[ClientCode]
FROM Clients
WHERE Clients.[ClientName]=#Client,
SELECT TOP 1 Personal.[DoctorCode]
FROM Personal
WHERE Personal.[DoctorName]=#Doctor
)
END
GO

Updating Values of a table from same table without using a select query

My Requirement
Updating Values of a table from same table without using a select query
this query won't effect any rows.
My aim : Update val2 of #table where slno=1 with the value of val2 of slno=2
Is there any other way without doing this method
Declare #val2 nvarchar(50)
select #val2=val2 from #table where slno=2
update #table set val2=#val2 where slno=1
create table #table
(
slno int identity(1,1),
val nvarchar(50),
val2 nvarchar(50)
)
insert into #table(val,val2)values('1',newID())
insert into #table(val,val2)values('1',newID())
insert into #table(val,val2)values('1',newID())
select * from #table
update #table set val2=T.val2
from #table T where slno=1 and T.slno=2
drop table #table
I have lot of records in the table.
So If i am selecting and update it may effect the performance.
Please, provide more info.
Do you have only 2 rows in your table?
Why do you need this kind of update?
I suppose, that your db structure is wrong, but I can't tell exactly, until you explain why do you need this.
Anyway I can suggest a poor way to do this without using select. You can self join the table. It would be better to have addition column, but if you don't have it, how's you should do
UPDATE T1
SET T1.val2 = T2.val2
FROM #table T1 INNER JOIN #table T2
ON T1.slno = 1 AND T2.slno = 2

How to COUNT values and and use it as a variable in a Stored Procedure

Basically, What i am trying to do is ;
The number of classes required is a variable. EG. The user could put 5 , 4 as a minimum.
Since i am new, i cant upload pictures, But here is a picture of my ER diagram, to get a idea of the table structures.
I am using sql server 2005
First off your question is poorly phrased; it is difficult to get a sense of what it is you are trying to achieve.
To get the number of rows from a dataset which meet the required condition, then use SELECT COUNT(0) FROM Tablename Where WhereCondition.
I can't see your ER diagram so I'll hypothesise; this should return attendance by class.
DECLARE #Students TABLE (id int, StudentName nvarchar(max));
DECLARE #Classes TABLE (id int, ClassName nvarchar(max))
DECLARE #StudentClassAttendance TABLE (ClassAttendanceID int, StudentId int, ClassId int, StartTime datetime)
SELECT sca.StudentID, s.StudentName, COUNT(sca.ClassAttendanceID), c.ClassName
FROM
#Students s
INNER JOIN #StudentClassAttendance sca
ON sca.StudentId = s.Id
INNER JOIN #Classes c
ON c.Id = sca.ClassId
GROUP BY
sca.StudentID, s.StudentName, ClassName

insert data into several tables

Let us say I have a table (everything is very much simplified):
create table OriginalData (
ItemName NVARCHAR(255) not null
)
And I would like to insert its data (set based!) into two tables which model inheritance
create table Statements (
Id int IDENTITY NOT NULL,
ProposalDateTime DATETIME null
)
create table Items (
StatementFk INT not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk)
)
Statements is the parent table and Items is the child table. I have no problem doing this with one row which involves the use of IDENT_CURRENT but I have no idea how to do this set based (i.e. enter several rows into both tables).
Thanks.
Best wishes,
Christian
Another possible method that would prevent the use of cursors, which is generally not a best practice for SQL, is listed below... It uses the OUTPUT clause to capture the insert results from the one table to be used in the insert to the second table.
Note this example makes one assumption in the fact that I moved your IDENTITY column to the Items table. I believe that would be acceptable, atleast based on your original table layout, since the primary key of that table is the StatementFK column.
Note this example code was tested via SQL 2005...
IF OBJECT_ID('tempdb..#OriginalData') IS NOT NULL
DROP TABLE #OriginalData
IF OBJECT_ID('tempdb..#Statements') IS NOT NULL
DROP TABLE #Statements
IF OBJECT_ID('tempdb..#Items') IS NOT NULL
DROP TABLE #Items
create table #OriginalData
( ItemName NVARCHAR(255) not null )
create table #Statements
( Id int NOT NULL,
ProposalDateTime DATETIME null )
create table #Items
( StatementFk INT IDENTITY not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk) )
INSERT INTO #OriginalData
( ItemName )
SELECT 'Shirt'
UNION ALL SELECT 'Pants'
UNION ALL SELECT 'Socks'
UNION ALL SELECT 'Shoes'
UNION ALL SELECT 'Hat'
DECLARE #myTableVar table
( StatementFk int,
ItemName nvarchar(255) )
INSERT INTO #Items
( ItemName )
OUTPUT INSERTED.StatementFk, INSERTED.ItemName
INTO #myTableVar
SELECT ItemName
FROM #OriginalData
INSERT INTO #Statements
( ID, ProposalDateTime )
SELECT
StatementFK, getdate()
FROM #myTableVar
You will need to write an ETL process to do this. You may want to look into SSIS.
This also can be done with t-sql and possibly temp tables. You may need to store unique key from OriginalTable in Statements table and then when you are inserting Items - join OriginalTable with Statements on that unique key to get the ID.
I don't think you could do it in one chunk but you could certainly do it with a cursor loop
DECLARE #bla char(10)
DECLARE #ID int
DECLARE c1 CURSOR
FOR
SELECT bla
FROM OriginalData
OPEN c1
FETCH NEXT FROM c1
INTO #bla
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO Statements(ProposalDateTime) VALUES('SomeDate')
SET #ID = SCOPE_IDENTITY()
INSERT INTO Items(StateMentFK,ItemNAme) VALUES(#ID,#bla)
FETCH NEXT FROM c1
INTO #bla
END
CLOSE c1
DEALLOCATE c1