Inner Join two table-Valued Parameters doesn't work - sql

I am trying to 'inner join' two table values parameters but when i execute the query it takes for ever and i have to stop debug in ms sql server management studio 2008.
The query:
#allClients [dbo].[ImportedClients] READONLY,
#NewClients [dbo].[ImportedClients] READONLY
--Update Clients table in db with new clients
UPDATE [dbo].[Clients]
SET
Email = ISNULL(ct.Email, x.Email),
FirstName = ISNULL(ct.FirstName, x.FirstName),
LastName = ISNULL(ct.LastName, x.LastName),
Telephone = ISNULL(ct.Telephone, x.Telephone),
Cellphone = ISNULL(ct.Cellphone, x.Cellphone),
FROM #NewClients ct
inner join #allClients x
ON (x.Email = ct.Email)
WHERE ct.Status > -1
What i am trying to do is: Update all the clients information for rows that exist in both #NewClients and #allClients so i used inner join.
Is it possible to JOIN two table-Valued Parameters?
This query doesn't (query doesn't complete without an error) work even with a few rows.
any suggestions?

You need to reference [dbo].[Clients] in the FROM clause of your SQL.
Something like this:
#allClients [dbo].[ImportedClients] READONLY,
#NewClients [dbo].[ImportedClients] READONLY
--Update Clients table in db with new clients
UPDATE [dbo].[Clients]
SET
Email = ISNULL(ct.Email, x.Email),
FirstName = ISNULL(ct.FirstName, x.FirstName),
LastName = ISNULL(ct.LastName, x.LastName),
Telephone = ISNULL(ct.Telephone, x.Telephone),
Cellphone = ISNULL(ct.Cellphone, x.Cellphone),
FROM [dbo].[Clients] c
INNER JOIN #NewClients ct ON (c.Email = ct.Email)
INNER JOIN #allClients x ON (x.Email = ct.Email)
WHERE ct.Status > -1

Related

Update with join and temp table

I have table that called hanpaka there I want to update the cardNum from temp table the connection between the two is IDMember and MemberId. but updating like this cause multiple cardNum not to the right MemberId why?
UPDATE Knowledge4All..Hanpaka
SET CardNum = (c.CardNumber )
FROM #Temp2 c inner join Hanpaka h on IDMember = h.MemberId`
Try using the alias in the update:
UPDATE h
SET CardNum = c.CardNumber
FROM #Temp2 c JOIN
Hanpaka h
ON c.IDMember = h.MemberId;
SQL Server does allow the table to be repeated in the update. However, it might get confused and your query might be doing a Cartesian product.

SQL Server mismatch row count in SELECT and UPDATE query with same conditions

I am trying to match the update and select query count with same condition. but row count is coming with big difference.
UPDATE Query:
UPDATE MKP set MKP.Quantity = MKP.Quantity + LQD.Quantity, ModifiedDate = GETDATE()
FROM IM_MarketPlace MKP
INNER JOIN IM_ChannelListings CL ON MKP.ListingID = CL.ListingID
INNER JOIN #ListingQuantityData LQD ON LQD.ChanelListingID = RTRIM(LTRIM((CL.ChannelListingID))) and LQD.SalesChannelID = CL.ChannelID
Left outer join IM_ListingVariations LV on LV.ListingCode = RTRIM(LTRIM((LQD.VariationSKU))) and MKP.ListingVariationID = LV.ID and CL.ListingID=LV.ListingID
WHERE MKP.IsActive =1 and MKP.IsDeleted=0 and CL.IsActive =1 and CL.IsDeleted=0
AND (LQD.VariationSKU is null OR (LQD.VariationSKU = LV.ListingCode and lv.ID = MKP.ListingVariationID))
Select Query
select count(mkp.ListingID) FROM IM_MarketPlace MKP
INNER JOIN IM_ChannelListings CL ON MKP.ListingID = CL.ListingID
INNER JOIN #ListingQuantityData LQD ON LQD.ChanelListingID = RTRIM(LTRIM((CL.ChannelListingID))) and LQD.SalesChannelID = CL.ChannelID
Left outer join IM_ListingVariations LV on LV.ListingCode = RTRIM(LTRIM((LQD.VariationSKU))) and MKP.ListingVariationID = LV.ID and CL.ListingID=LV.ListingID
WHERE MKP.IsActive =1 and MKP.IsDeleted=0 and CL.IsActive =1 and CL.IsDeleted=0
AND (LQD.VariationSKU is null OR (LQD.VariationSKU = LV.ListingCode and lv.ID = MKP.ListingVariationID))
Please help me out for this.
and also please let me know how ##rowcount will work for update query.
this will happen if there is a one to many relationship between at least two of the tables involved in the joins.
The SELECT will count all rows including those multiplied out by the join. The UPDATE will just count the unique rows in IM_MarketPlace affected by the UPDATE.
Where there is a one to many relationship it is not deterministic which of the "many" rows joining to a specific row in IM_MarketPlace are used as the source in the update for that row.

Access - query update with Inner Join

I have this query:
UPDATE client
SET client.[client_history] = 10
FROM [T_CLIENT] AS client
INNER JOIN (SELECT [client_id], SUM([final_price])
FROM [T_PURCHASE]
GROUP BY [client_id]) AS p
ON client.[client_id] = p.[client_id]
When i execute this query on access, i get "Syntax Error".
Did you see something wrong?
Thank you
You can use a DSUM to sum from a different table in an update query. Subqueries with aggregates won't work, because they're not updateable.
UPDATE t_client
SET [client_history] = DSUM("final_price", "T_PURCHASE", "client_id = " & client_id)
Does the syntax work without FROM:
UPDATE [T_CLIENT] AS client INNER JOIN
(SELECT [client_id], SUM([final_price])
FROM [T_PURCHASE]
GROUP BY [client_id]
) AS p
ON client.[client_id] = p.[client_id]
SET client.[client_history] = 10;

Check and get Parent Tables - Firebird

Anyone can help me a bit?
I use this Query to get all the constraint names, foreign tables, fields with their contraint tables and fields...
select distinct Con.rdb$constraint_name,
Rel.rdb$relation_name TableName ,Rel.rdb$field_name FieldName,
FCon.rdb$Relation_Name ForeignTableName, FIseg.rdb$Field_Name ForeignFieldName
from rdb$relation_fields Rel
inner join rdb$relation_constraints Con on (Con.rdb$relation_name = Rel.rdb$relation_name and Con.rdb$constraint_type like 'FOREIGN%')
inner join rdb$indices IDX on (IDX.rdb$index_name = Con.rdb$index_name)
inner join rdb$index_segments ISeg on (ISeg.rdb$index_name = Idx.rdb$index_name and ISeg.rdb$Field_Name = Rel.rdb$field_name)
inner join rdb$Relation_Constraints FCon on (FCon.rdb$index_name = Idx.rdb$Foreign_Key)
inner join rdb$index_segments FIseg on (FISeg.rdb$index_name = Idx.rdb$Foreign_key and FISeg.rdb$Field_Position = ISeg.rdb$Field_Position)
where Rel.rdb$relation_name not like 'RDB$%' and
FCon.rdb$Relation_Name <> Rel.rdb$relation_name and
FCon.rdb$Relation_Name = :TABLENAME
I would like to check whether the specified table (:TABLENAME) has a parent table or not and I need it's name, foreignfieldname etc like in my first query.
For example:
Applications -> Licenses -> Licenseinfos -> ''
-> Registrations -> ''
If I add Licenseinfos I would like to get "Licenses"
If I add Registrations I would like to get "Licenses"
Thanks for the answers! I use firebird 2.5
The simplest way to do this is using the following query. It identifies both sides of the constraint using the table RDB$REF_CONSTRAINTS, this doesn't need to do anything with the RDB$INDICES table (which would be a complication if you had keys with multiple columns):
select
PK.RDB$RELATION_NAME as PKTABLE_NAME
,FK.RDB$RELATION_NAME as FKTABLE_NAME
from RDB$RELATION_CONSTRAINTS FK
inner join RDB$REF_CONSTRAINTS RC on FK.RDB$CONSTRAINT_NAME = RC.RDB$CONSTRAINT_NAME
inner join RDB$RELATION_CONSTRAINTS PK on PK.RDB$CONSTRAINT_NAME = RC.RDB$CONST_NAME_UQ
where FK.RDB$RELATION_NAME = :TABLENAME

SQL Server 2008: Select then update statement

I'm doing a INNER JOIN across 6 tables for a module for my application, basically it takes the prostaff an gets their name and email, and compares that to a list of job applicants.
On the mod_employmentAppJobs I need to set a column for each row selected to true. Basically this sets a flag that tells the sql not to select the column because we already sent an email on that user. It's a bit field.
How do I set the emailSent field to true on a SQL statement? -- Coldfusion 8 is the Application server, just FYI....
SELECT *
FROM pro_Profile p
INNER JOIN pro_Email e ON p.profileID = e.profileID
INNER JOIN mod_userStatus m ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a ON p.profileID = a.departmentID
<!--- Join Job titles to the jobs --->
INNER JOIN mod_employmentAppJobs b ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
You have a couple of choices.
1) Use a temp table and select data there first, update the mod_employmentAppJobs, and perform a select from the temp table to get your data retrieved.
So, it would look something like this.
create a temp table
CREATE TABLE #tmpTABLE
(
EmailAddress varchar(100),
JobTitle varchar(50),
JobTitleId bigint
......
)
Insert into it
INSERT INTO #tmpTable
SELECT EmailAddress,JobTitle, ........
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
Update the source table (I'd recommend an index on jobTitleId in the temp table for performance if applicable)
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM mod_employmentAppJobs b
INNER JOIN #tmpTable tmp
ON b.jobTitleID=tmp.jobTitleID
Get the actual data back to the app layer
SELECT * FROM #tmpTable
For better taste, I recommend sprinkling with BEGIN TRAN...COMMIT...ROLLBACK and BEGIN TRY..END TRY BEGIN CATCH...END CATCH to taste and to business requirements.
Also, it's good manners to drop the temp table after you are done with it, even though SQL server will not take offense if you don't.
2) You can use the OUTPUT clause of the update statement.
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
OUTPUT inserted.*
This should get you the resultset right back to your app layer
You could store the result in a temporary table. You can use the data in the temporary table, and still return it at the end. It's a lot of typing but pretty straightforward:
-- Select data into temporary table
declare #result table (jobTitleID int, ...)
INSERT #result
(jobTitleID, ...)
SELECT jobTitleID
FROM pro_Profile p
...
-- Update unreadMail flag
update mod_employmentAppJobs
set unreadMail = 'False'
where jobTitleID in (select jobTitleId from #result)
-- Return result to application
select jobTitleId, ...
from #result
If you need to update and then return the data then probably the best is to use a Stored Procedure, where you first query the data, update it and then return it.
Well, this is just an idea, not the best solution.
You could get data (for which bit is false) in a DataReader and then execute a Command setting bit to true for ids contained in Dataset.
Dataset returns data you need...
I just tacked a on the end and it worked:
UPDATE mod_employmentAppJobs
SET emailSent = 'True'