If Else condition for temporary table - sql

IF (#Track = 'SearchSelect')
BEGIN
IF(#limitedAccess = 'true')
BEGIN
SELECT CusLst.CustomerId, MAX(CusCon.CustomerContactId) AS CustomerContactId
INTO #CustomerList1
FROM CustomerList CusLst
LEFT JOIN CustomerContact CusCon ON CusLst.CustomerId = CusCon.CustomerId
INNER JOIN CustomerUser ON CusLst.CustomerId = CustomerUser.CustomerId
WHERE CustomerUser.UserId = #userId
GROUP BY CusLst.CustomerId
END
ELSE
BEGIN
SELECT CusLst.CustomerId, MAX(CusCon.CustomerContactId) AS CustomerContactId
INTO #CustomerList1
FROM CustomerList CusLst
LEFT JOIN CustomerContact CusCon ON CusLst.CustomerId = CusCon.CustomerId
GROUP BY CusLst.CustomerId
END
This is causing an error as customerList1 already exists. What to do if I want to fill temporary table based on the condition in my stored procedure?

Add this code before you start working
IF Object_id('tempdb..#CustomerList1') IS NOT NULL
BEGIN
DROP TABLE #CustomerList1
END

EDITED:
You probably have created your temp table either remove your create table or use
INSERT INTO #customerlist1(columns)
SELECT columns
FROM customerlist
since this
SELECT CusLst.CustomerId, MAX(CusCon.CustomerContactId) AS CustomerContactId
INTO #CustomerList1
FROM CustomerList CusLst
LEFT JOIN CustomerContact CusCon ON CusLst.CustomerId = CusCon.CustomerId
INNER JOIN CustomerUser ON CusLst.CustomerId = CustomerUser.CustomerId
WHERE CustomerUser.UserId = #userId
GROUP BY CusLst.CustomerId
creates a new temp table that's why it throws an error.
https://www.w3schools.com/sql/sql_select_into.asp

First check your temp table exists or not in your database.IF exists means drop your temp table and then create new one.
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE xtype in ('U') AND id =
object_id(N'tempdb..#CustomerList1') )
DROP TABLE #CustomerList1;

Related

Sql Query with Temp tables in Visual Studio 2010 data grid

I apologize up front if this has been answered, i read several other posts and didn't see a clear answer to my question. I am a beginner at VS2010. Basically i have the below query and i want it to display in the data grid view when i run my program.
I can use VS2010 to join two actual tables but as you can see below the temp tables are very important.
IF OBJECT_ID('tempdb..#tempbatch') IS NOT NULL DROP TABLE #tempbatch
IF OBJECT_ID('tempdb..#tempbatch2') IS NOT NULL DROP TABLE #tempbatch2
IF OBJECT_ID('tempdb..#tempbatch1') IS NOT NULL DROP TABLE #tempbatch1
IF OBJECT_ID('tempdb..#tempbatch3') IS NOT NULL DROP TABLE #tempbatch3
IF OBJECT_ID('tempdb..#tempbatch4') IS NOT NULL DROP TABLE #tempbatch4
IF OBJECT_ID('tempdb..#tempbatch5') IS NOT NULL DROP TABLE #tempbatch5
IF OBJECT_ID('tempdb..#tempbatch6') IS NOT NULL DROP TABLE #tempbatch6
IF OBJECT_ID('tempdb..#tempbatch7') IS NOT NULL DROP TABLE #tempbatch7
IF OBJECT_ID('tempdb..#tempbatch8') IS NOT NULL DROP TABLE #tempbatch8
IF OBJECT_ID('tempdb..#tempbatch9') IS NOT NULL DROP TABLE #tempbatch9
IF OBJECT_ID('tempdb..#tempbatch10') IS NOT NULL DROP TABLE #tempbatch10
create table #tempbatch (rowid bigint primary key identity(1,1), shipmentno varchar(64))
insert into #tempbatch select * from #unitnames
select distinct b.dcsID, a.BoxType, b.BoxNO, b.shipmentno, b.PaletteWithinShipment into #tempbatch1 from #tempbatch c
join dva..Boxmapping as a
on c.shipmentno = a.shipmentno
join dva..Boxmapping as b
on a.boxno = b.BoxNO
--where b.shipmentno = '#rmn'
group by b.dcsID, a.BoxType, b.BoxNO, b.shipmentno, b.PaletteWithinShipment
order by b.PaletteWithinShipment, b.BoxNO
--select dcsid,boxtype,boxno,shipmentno from #tempbatch1
select distinct a.dcsid,b.dcsid as manifestDCS,b.rmn into #tempbatch3 from #tempbatch1 a
left outer join dva..manifestDCS b
on a.dcsid = b.dcsid
select distinct b.dcsid,a.rmn into #tempbatch5 from #tempbatch3 a
left outer join dva..manifestdcs b
on a.rmn = b.rmn
select b.dcsid as deliverexDCSID,a.dcsid,a.rmn,pbatch into #tempbatch4 from #tempbatch5 a
left outer join #tempbatch1 b
on a.dcsid = b.dcsid
join dva..document c
on a.dcsid = c.dcsid
where a.dcsid not in (select dcsid from dva..document where ftpstime is null) and a.dcsid not in (select dcsid from dva..boxmapping)
delete from #tempbatch4 where deliverexdcsid is not null
----- ******************************** START OF SECOND QUERY *********************************-------------
select * into #tempbatch6 from dva..Boxmapping
select distinct c.rmn,c.dcsid,b.dcsid as BoxDCSID,a.pbatch into #tempbatch8 from #tempbatch4 a
left outer join dva..manifestDCS b
on a.dcsid = b.dcsid
left outer join dva..manifestdcs c
on b.rmn = c.rmn
select distinct c.rmn,c.dcsid as Missing,a.dcsid,d.BoxNO,d.boxtype,e.palette,e.PaletteWithinShipment,e.shipmentno into #tempbatch9 from #tempbatch8 a
left outer join #tempbatch4 c
on a.rmn = c.rmn
left outer join dva..boxmapping d
on b.dcsid = d.dcsid
left outer join dva..boxmapping e
on d.boxno = e.boxno
delete from #tempbatch9 where dcsID is null
delete from #tempbatch9 where boxno is null
delete from #tempbatch9 where palette is null
select distinct rmn,missing,boxno,boxtype,PaletteWithinShipment,shipmentno from #tempbatch9
order by rmn,PaletteWithinShipment
Wrap the whole of your query in a stored procedure, i.e.
CREATE PROCEDURE dbo.MyData
AS
SET NOCOUNT ON;
BEGIN
<insert your SQL here>
END;
Back in Visual Studio you will need to open a connection to your database, then open a command that you will use in conjunction with a data reader. There should be plenty of examples of how to do this, but I will give you a very short sample (sorry it's in C#, I don't touch VB):
using (var con = new SqlConnection("Server=WHATEVERSERVER;Database=WHATEVERDBS;Trusted_Connection=True;"))
{
con.Open();
using (var com = con.CreateCommand())
{
com.CommantText = "EXECUTE <MyDatabase>.dbo.MyData;";
using (var dr = com.ExecuteReader())
{
while (dr.Read())
{
var row = new string[7];
row[0] = dr["rmn"].ToString();
row[1] = dr["missing"].ToString();
etc...
MyDataGrid.Rows.Add(row);
}
}
}
}
Finally, you can just pull back a row count from your data grid, to get the number of rows of data that you want to display in a window.
If you can't create a stored procedure then you could type the entire SQL script into the command text bit, but you would have to be very careful with the carriage returns, spacing, literals, quotes, etc.
Again, apologies that my example code is in C#, I was just wanting to give you a very basic framework, so at the very least you know what to go and type into Google...

How can I perform the Count function with a where clause?

I have my database setup to allow a user to "Like" or "Dislike" a post. If it is liked, the column isliked = true, false otherwise (null if nothing.)
The problem is, I am trying to create a view that shows all Posts, and also shows a column with how many 'likes' and 'dislikes' each post has. Here is my SQL; I'm not sure where to go from here. It's been a while since I've worked with SQL and everything I've tried so far has not given me what I want.
Perhaps my DB isn't setup properly for this. Here is the SQL:
Select trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname, Count(trippin.LikesDislikesData.liked)
as TimesLiked from trippin.PostData
inner join trippin.AccountData on trippin.PostData.accountid = trippin.AccountData.id
inner join trippin.CategoryData on trippin.CategoryData.id = trippin.PostData.categoryid
full outer join trippin.LikesDislikesData on trippin.LikesDislikesData.postid =
trippin.PostData.id
full outer join trippin.LikesDislikesData likes2 on trippin.LikesDislikesData.accountid =
trippin.AccountData.id
Group By (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
Here's my table setup (I've only included relevant columns):
LikesDislikesData
isliked(bit) || accountid(string) || postid(string
PostData
id(string) || posttext || accountid(string)
AccountData
id(string) || username(string)
CategoryData
categoryname(string)
Problem 1: FULL OUTER JOIN versus LEFT OUTER JOIN. Full outer joins are seldom what you want, it means you want all data specified on the "left" and all data specified on the "right", that are matched and unmatched. What you want is all the PostData on the "left" and any matching Likes data on the "right". If some right hand side rows don't match something on the left, then you don't care about it. Almost always work from left to right and join results that are relevant.
Problem 2: table alias. Where ever you alias a table name - such as Likes2 - then every instance of that table within the query needs to use that alias. Straight after you declare the alias Likes2, your join condition refers back to trippin.LikesDislikesData, which is the first instance of the table. Given the second one in joining on a different field I suspect that the postid and accountid are being matched on the same row, therefore it should be AND together, not a separate table instance. EDIT reading your schema closer, it seems this wouldn't be needed at all.
Problem 3: to solve you Counts problem separate them using CASE statements. Count will add the number of non NULL values returned for each CASE. If the likes.liked = 1, then return 1 otherwise return NULL. The NULL will be returned if the columns contains a 0 or a NULL.
SELECT trippin.PostData.Id, trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname,
SUM(CASE WHEN likes.liked = 1 THEN 1 ELSE 0 END) as TimesLiked,
SUM(CASE WHEN likes.liked = 0 THEN 1 ELSE 0 END) as TimesDisLiked
FROM trippin.PostData
INNER JOIN trippin.AccountData ON trippin.PostData.accountid = trippin.AccountData.id
INNER JOIN trippin.CategoryData ON trippin.CategoryData.id = trippin.PostData.categoryid
LEFT OUTER JOIN trippin.LikesDislikesData likes ON likes.postid = trippin.PostData.id
-- remove AND likes.accountid = trippin.AccountData.id
GROUP BY trippin.PostData.Id, (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
Then "hide" the PostId column in the User Interface.
Instead of selecting Count(trippin.LikesDislikesData.liked) you could put in a select statement:
Select AccountData.username, PostData.posttext, CategoryData.categoryname,
(select Count(*)
from LikesDislikesData as likes2
where likes2.postid = postdata.id
and likes2.liked = 'like' ) as TimesLiked
from PostData
inner join AccountData on PostData.accountid = AccountData.id
inner join CategoryData on CategoryData.id = PostData.categoryid
USE AdventureWorksDW2008R2
GO
SET NOCOUNT ON
GO
/*
Default
*/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRAN
IF OBJECT_ID('tempdb.dbo.#LikesDislikesData') IS NOT NULL
BEGIN
DROP TABLE #LikesDislikesData
END
CREATE TABLE #LikesDislikesData(
isLiked bit
,accountid VARCHAR(50)
,postid VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#PostData') IS NOT NULL
BEGIN
DROP TABLE #PostData
END
CREATE TABLE #PostData(
postid INT IDENTITY(1,1) NOT NULL
,accountid VARCHAR(50)
,posttext VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#AccountData') IS NOT NULL
BEGIN
DROP TABLE #AccountData
END
CREATE TABLE #AccountData(
accountid INT
,username VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#CategoryData') IS NOT NULL
BEGIN
DROP TABLE #CategoryData
END
CREATE TABLE #CategoryData(
categoryname VARCHAR(50)
);
INSERT INTO #AccountData VALUES ('1', 'user1')
INSERT INTO #PostData VALUES('1','this is a post')
INSERT INTO #LikesDislikesData (isLiked ,accountid, postid)
SELECT '1', P.accountid, P.postid
FROM #PostData P
WHERE P.posttext = 'this is a post'
SELECT *
FROM #PostData
SELECT *
FROM #LikesDislikesData
SELECT *
FROM #AccountData
SELECT COUNT(L.isLiked) 'Likes'
,P.posttext
,A.username
FROM #PostData P
JOIN #LikesDislikesData L
ON P.accountid = L.accountid
AND L.IsLiked = 1
JOIN #AccountData A
ON P.accountid = A.accountid
GROUP BY P.posttext, A.username
SELECT X.likes, Y.dislikes
FROM (
(SELECT COUNT(isliked)as 'likes', accountid
FROM #LikesDislikesData
WHERE isLiked = 1
GROUP BY accountid
) X
JOIN
(SELECT COUNT(isliked)as 'dislikes', accountid
FROM #LikesDislikesData
WHERE isLiked = 0
GROUP BY accountid) Y
ON x.accountid = y.accountid)
IF (XACT_STATE() = 1 AND ERROR_STATE() = 0)
BEGIN
COMMIT TRAN
END
ELSE IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN
END
How do you think about the solution? We create a new table SummaryReport(PostID,AccountID,NumberOfLikedTime,NumberOfDislikedTimes).
An user clicks on LIKE or DISLIKE button we update the table. After that, you can query as you desire. Another advantage, the table can be served reporting purpose.

DELETE Row of a table with a condition with another table

I have the following SQL which is working,
IF NOT EXISTS(SELECT 1 FROM [Batch] B
INNER JOIN BatchProducts BP
ON (B.ID = BP.BatchID)
WHERE Bp.ID = #ID AND B.RetailerID = #RetailerID)
BEGIN
RETURN;
END
DELETE FROM BatchProducts WHERE BatchProducts.ID = #ID;
But it is composed with 2 statements. I want to use a single DELETE with a condition that RetailerID must match in BatchProducts table.
You can do it this way:
DELETE FROM BatchProducts
WHERE BatchProducts.ID = #ID
AND EXISTS (SELECT * FROM [Batch]
WHERE [Batch].ID = BatchProducts.BatchID AND [Batch].RetailerID = #RetailerID)
Is there a particular reason you need to check if it exists?
DELETE bp
FROM BatchProducts bp
JOIN Batch b
ON bp.BatchID = b.ID
WHERE bp.ID = #ID
AND b.RetailerID = #RetailerID

SQL Server 2005 - Using temporary tables in a multi-user environment

I have a problem with this procedure. It uses a couple of temporary tables which it drops and recreates. This is causing loads of crashes, and I can only presume that conflicts are arising.
ALTER PROCEDURE [dbo].[AdditionalVisits_SelectByOrigID]
(
#orig_job_ID int
)
as
if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'additionalVisitsPodsCnt')
drop table additionalVisitsPodsCnt;
SELECT CONVERT(bit, COUNT(PODS.podID)) AS cnt, AdditionalVisits.this_job_id, AdditionalVisits.orig_job_id
INTO additionalVisitsPodsCnt
FROM PODS RIGHT OUTER JOIN
AdditionalVisits ON PODS.jobID = AdditionalVisits.this_job_id
GROUP BY AdditionalVisits.this_job_id, AdditionalVisits.orig_job_id
HAVING (AdditionalVisits.orig_job_id = #orig_job_ID)
if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'additionalVisitsPhotosCnt')
drop table additionalVisitsPhotosCnt;
SELECT CONVERT(bit, COUNT(Photos.photoID)) AS cnt, AdditionalVisits.this_job_id, AdditionalVisits.orig_job_id
INTO additionalVisitsPhotosCnt
FROM Photos RIGHT OUTER JOIN
AdditionalVisits ON Photos.jobID = AdditionalVisits.this_job_id
GROUP BY AdditionalVisits.this_job_id, AdditionalVisits.orig_job_id
HAVING (AdditionalVisits.orig_job_id = #orig_job_ID)
SELECT AdditionalVisits.id, AdditionalVisits.this_job_ID, AdditionalVisits.orig_job_ID, AdditionalVisits.reason, AdditionalVisits.date, ThisJob.Job_Reference_No,
ThisJob.Job_POD_Filename, ThisJob.Job_Photo_Filename, ThisJob.Job_Signed_For_Name, ThisJob.Job_Value, ThisJob.Job_Advance_Payment,
ThisJob.Job_Eoj_Payment, ThisJob.Job_Status, ThisJob.Job_Date_Added, ThisJob.Job_Start_Date, additionalVisitsPhotosCnt.cnt AS Job_Photo_Supplied,
additionalVisitsPodsCnt.cnt AS Job_POD_Supplied
FROM AdditionalVisits INNER JOIN
Jobs AS ThisJob ON AdditionalVisits.this_job_ID = ThisJob.Job_ID INNER JOIN
additionalVisitsPodsCnt ON AdditionalVisits.this_job_ID = additionalVisitsPodsCnt.this_job_id INNER JOIN
additionalVisitsPhotosCnt ON AdditionalVisits.this_job_ID = additionalVisitsPhotosCnt.this_job_id
WHERE (AdditionalVisits.orig_job_ID = #orig_job_ID) AND (ThisJob.Job_Status <> 7)
The errors I get are as follow:
Cannot drop the table 'additionalVisitsPodsCnt', because it does not exist or you do not have permission. There is already an object named 'additionalVisitsPodsCnt' in the database.
or
Invalid object name 'additionalVisitsPhotosCnt'.
These errors are intermittent. Sometimes it just works.
Is there a better way of doing this?
Sure, if this table is only used from this one procedure, use a "real" local temporary table (created in tempdb), by prefixing the table name with #:
SELECT CONVERT(bit, COUNT(PODS.podID)) AS cnt,
AdditionalVisits.this_job_id, AdditionalVisits.orig_job_id
INTO #additionalVisitsPodsCnt
FROM PODS ....
This way it is isolated from all other sessions, even if concurrent calls to this procedure are made by others.
Here is the normal pattern I used for a #temp table. (Notice the "#" prefix).
IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
drop table #TableOne
end
CREATE TABLE #TableOne
(
SurrogateKey int ,
NameOf varchar(12)
)
/*
Do something with temp table
*/
IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
drop table #TableOne
end
Consider using table variables instead.
This StackOverflow topic explains it better than I would... ;)

How to delete with these conditions?

How can I delete rows which meet several conditions from a table without primary key? (actually the primary key is formed by every column)
After so many tries I have a code that first creates a temporary table where it inserts the rows I want to delete and finally I try to delete the rows from original table which meet the conditions comparing to temporary table.
But it gives me the error about cannot linking the several parts identifier #temp.idCarga
Maybe it's easy but I have been trying so much time and I cannot focus properly.
CREATE TABLE #TEMP
(
CC int,
idCarga int,
Tipo nvarchar(50),
Importe float,
Bloque nvarchar(50),
idsistema int
)
INSERT INTO #TEMP(CC,idCarga,Importe,Bloque,Tipo,IdSistema)
select distinct CI.CC,CI.idCarga,CI.Importe,CI.Bloque,CI.Tipo,CI.idSistema
from CONT_INGRESOS_InformeMayor CI
INNER JOIN
(
SELECT idCarga,CC,Bloque,Importe,TIpo
FROM CONT_INGRESOS_InformeMayor
) CI2
ON CI.CC = CI2.CC
AND CI.Bloque = CI2.Bloque
AND CI.TIpo <> CI2.Tipo
WHERE CI.idCarga = #idCarga
AND CI2.idCarga = #idCarga
AND CI.Importe = 0
DELETE
FROM CONT_INGRESOS_InformeMayor
WHERE idCarga = #temp.idCarga
AND tipo = #temp.tipo
AND importe = #temp.importe
and bloque = #temp.bloque
You missed a join on your DELETE. Try this:
DELETE _d
FROM CONT_INGRESOS_InformeMayor AS _d
INNER JOIN #temp AS _t
ON _d.idCarga = _t.idCarga
AND _d.tipo = _t.tipo
AND _d.importe = _t.importe
AND _d.bloque = _t.bloque
Your DELETE is missing a JOIN to your #temp table
DELETE t1
FROM CONT_INGRESOS_InformeMayor t1
INNER JOIN #temp t
ON t1.idCarga = t.idCarga
AND t1.tipo = t.tipo
AND t1.importe = t.importe
and t1.bloque = t.bloque
On the other hand, you could try deleting the rows without involving a temporary table:
DELETE FROM CI
from CONT_INGRESOS_InformeMayor CI
INNER JOIN
(
SELECT idCarga,CC,Bloque,Importe,TIpo
FROM CONT_INGRESOS_InformeMayor
) CI2
ON CI.CC = CI2.CC
AND CI.Bloque = CI2.Bloque
AND CI.TIpo <> CI2.Tipo
WHERE CI.idCarga = #idCarga
AND CI2.idCarga = #idCarga
AND CI.Importe = 0