Related
What I'm trying to achieve is to check if a table exists:
if it exists, just truncate it
if it does not exist, create the table
Below is my code but I get an error.
Code:
--Check if table exists
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[Com_SQL_Server_Agent_Monitor]')
AND type in (N'U'))
TRUNCATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
ELSE
--Create table if not exist
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
(
[job_id] [uniqueidentifier] NULL,
[originating_server] [nvarchar](30) NULL,
[name] [nvarchar](128) NULL,
[enabled] [tinyint] NULL,
[description] [nvarchar](512) NULL,
[start_step_id] [int] NULL,
[category] [nvarchar](128) NULL,
[owner] [nvarchar](128) NULL,
[notify_level_eventlog] [int] NULL,
[notify_level_email] [int] NULL,
[notify_level_netsend] [int] NULL,
[notify_level_page] [int] NULL,
[notify_email_operator] [nvarchar](128) NULL,
[notify_netsend_operator] [nvarchar](128) NULL,
[notify_page_operator] [nvarchar](128) NULL,
[delete_level] [int] NULL,
[date_created] [datetime] NULL,
[date_modified] [datetime] NULL,
[version_number] [int] NULL,
[last_run_date] [int] NULL,
[last_run_time] [int] NULL,
[last_run_outcome] [int] NULL,
[next_run_date] [int] NULL,
[next_run_time] [int] NULL,
[next_run_schedule_id] [int] NULL,
[current_execution_status] [int] NULL,
[current_execution_step] [nvarchar](128) NULL,
[current_retry_attempt] [int] NULL,
[has_step] [int] NULL,
[has_schedule] [int] NULL,
[has_target] [int] NULL,
[type] [int] NULL
) ON [PRIMARY]
GO
This is the error I get:
There is already an object named 'Com_SQL_Server_Agent_Monitor' in the database
Any ideas what I'm missing?
The biggest problem in your code is the fact that you have multiple SQL statements in your ELSE block - but they're not framed by a BEGIN ... END.
So really what you have right now is:
IF EXISTS (....)
TRUNCATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
ELSE
SET ANSI_NULLS ON
-- these statements will be executed ALWAYS - no matter what the
-- IF EXISTS() check returns!
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
......
So even if the table exists, and gets truncated - the SET QUOTED_IDENTIFIER ON and the CREATE TABLE statement will still be executed! That's why you're getting an error "table already exists".
What you need to do is:
IF EXISTS (....)
TRUNCATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
ELSE
BEGIN
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[Com_SQL_Server_Agent_Monitor]
......
END
In my database I have about 10 tables connected in one central table (Mobile). This table (Mobile) has a column called price which is the sum of the prices of all other nested tables. I would like that when price of another table (like Battery, Camera, ...) is updated, the price of the central table (Mobile) would be updated too.
I will show the schema of central table and two more (for reducing code, other nested tables are so similar)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table_mobile]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[processor] [int] NOT NULL,
[memory_ram] [int] NOT NULL,
[memory_rom] [int] NOT NULL,
[operating_system] [int] NOT NULL,
[graphic] [int] NOT NULL,
[screen] [int] NOT NULL,
[battery] [int] NOT NULL,
[camera] [int] NOT NULL,
[material] [int] NOT NULL,
[extra] [int] NOT NULL,
[price] [decimal](18, 2) NOT NULL,
[created_by] [int] NOT NULL,
[created_at] [timestamp] NOT NULL,
CONSTRAINT [PK_mobiles]
PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table_battery]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[capacity] [int] NOT NULL,
[description] [varchar](250) NOT NULL,
[image] [image] NOT NULL,
[price] [decimal](18, 2) NOT NULL,
CONSTRAINT [PK_table_battery]
PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[table_camera]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[megapixels] [int] NOT NULL,
[description] [varchar](250) NOT NULL,
[image] [image] NOT NULL,
[price] [decimal](18, 2) NOT NULL,
CONSTRAINT [PK_table_camera]
PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
As I say, I think that my purpose should be achieve with a trigger but any other suggest is accepted.
I'll show you what I want to do by programming in C#:
table_mobile.price = table_battery.price + table_camera.price + ... + table_XXX.price
Any idea how can I achive my trouble?
Thank you.
EDIT 1:
Using SSMS... I have created this template for a Trigger:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER <Schema_Name, sysname, Schema_Name>.<Trigger_Name, sysname, Trigger_Name>
ON <Schema_Name, sysname, Schema_Name>.<Table_Name, sysname, Table_Name>
AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE>
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
END
GO
I have not worked with SQL Server for a while, so forgive me if there are any typos, but basically you will need to create a trigger for each of the tables linked to mobile and add the difference of the new and the old value to the price of the mobile:
create trigger PriceChange on table_battery
after update
as
BEGIN
update table_mobile
set price = table_mobile.price + i.price
from table_mobile
inner join INSERTED i
on table.mobile.id = i.id;
update table_mobile
set price = table_mobile.price - d.price
from table_mobile
inner join DELETED d
on table.mobile.id = d.id;
END
Note that we do separate updates, because the id might have changed. If the id stays the same, then you can use a single update with a difference. The code is untested, so if there are any problems, then please, let me know.
EDIT
You may also do this from application level where you trigger the updates. After any such update you can run an update for table_mobile, adding the values. The benefit would be that you can do the calculation only once if you know that several prices for the same mobiles will be changed.
EDIT2
Apparently this command should be used inside the trigger:
UPDATE [dbo].[table_mobile]
SET price = table_mobile.price + i.price - d.price
FROM [dbo].[table_mobile],
INSERTED i,
DELETED d
WHERE battery = d.id
This is an example of the view I mentioned:
create view MobileWithPriceAggregate as
select [id]
, [name]
, [processor]
, [memory_ram]
, [memory_rom]
, [operating_system]
, [graphic]
, [screen]
, [battery]
, [camera]
, [material]
, [extra]
, price = m.price+b.price+c.price
from [table_mobile] m
join [table_battery] b on b.id=m.battery
join [table_camera] c on c.id=m.camera
Note: if not all Mobiles have a camera, then you need to use left join and null handle like ISNULL(c.price,0)
I have 2 tables (BSH_FLD1) and (BSH_IMGVER).These tables are related by a third table called (BSH_FLDIMG1).One id field in (BSH_FLD1) can relate to many id images in (BSH_IMGVER).
The script for creating the tables is this :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[BSH_FLD1](
[IDFIELD] [int] NOT NULL,
[EC_NOP] [int] NULL,
[EC_NOI] [int] NULL,
[EC_NOA] [int] NULL,
[INTESTIMI] [varchar](20) COLLATE Albanian_CI_AI NULL,
[KUTIA] [int] NULL,
[DREJTORIA] [varchar](30) COLLATE Albanian_CI_AI NULL,
[DOSJA] [int] NULL,
[VITI] [int] NULL,
[AFATI] [varchar](20) COLLATE Albanian_CI_AI NULL,
[FILLIMI] [datetime] NULL,
[FUNDI] [datetime] NULL,
[FAQE] [int] NULL,
[FILMI] [int] NULL,
[BLIP] [varchar](10) COLLATE Albanian_CI_AI NULL,
[DEPARTAMENTI] [varchar](150) COLLATE Albanian_CI_AI NULL,
[LLOJI_I_DOKUMENTIT] [varchar](50) COLLATE Albanian_CI_AI NULL,
[ADRESIMI] [varchar](30) COLLATE Albanian_CI_AI NULL,
[KLASIFIKIMI] [varchar](30) COLLATE Albanian_CI_AI NULL,
[KOMENTE] [varchar](255) COLLATE Albanian_CI_AI NULL,
[FRAKSION] [int] NULL,
[OBJEKTI] [varchar](50) COLLATE Albanian_CI_AI NULL,
CONSTRAINT [P080318150042500] PRIMARY KEY CLUSTERED
(
[IDFIELD] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[BSH_FLDIMG1](
[IDFIELD] [int] NOT NULL,
[IDIMAGE] [int] NOT NULL,
CONSTRAINT [P080318150042718] PRIMARY KEY CLUSTERED
(
[IDFIELD] ASC,
[IDIMAGE] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [eCodis_Data]
GO
ALTER TABLE [dbo].[BSH_FLDIMG1] WITH CHECK ADD CONSTRAINT [F080318150042828] FOREIGN KEY([IDFIELD])
REFERENCES [dbo].[BSH_FLD1] ([IDFIELD])
GO
ALTER TABLE [dbo].[BSH_FLDIMG1] WITH CHECK ADD CONSTRAINT [F080318150042937] FOREIGN KEY([IDIMAGE])
REFERENCES [dbo].[BSH_IMG] ([IDIMAGE])
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[BSH_IMGVER](
[IDIMAGE] [int] NOT NULL,
[VERSION] [int] NOT NULL,
[IDDATASET] [int] NULL,
[IDVOLUME] [int] NULL,
[IMAGE] [varchar](250) COLLATE Albanian_CI_AI NULL,
[CHECKEDOUT] [smallint] NULL,
[CHECKOUTBY] [varchar](250) COLLATE Albanian_CI_AI NULL,
[ADDDATE] [datetime] NULL,
[ADDBY] [varchar](250) COLLATE Albanian_CI_AI NULL,
[ORGFNAME] [varchar](250) COLLATE Albanian_CI_AI NULL,
[NROFPAGES] [int] NULL,
CONSTRAINT [P080318150040953] PRIMARY KEY CLUSTERED
(
[IDIMAGE] ASC,
[VERSION] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [eCodis_Data]
GO
ALTER TABLE [dbo].[BSH_IMGVER] WITH CHECK ADD CONSTRAINT [F080318150041062] FOREIGN KEY([IDIMAGE])
REFERENCES [dbo].[BSH_IMG] ([IDIMAGE])
GO
ALTER TABLE [dbo].[BSH_IMGVER] WITH CHECK ADD CONSTRAINT [F080318150041171] FOREIGN KEY([IDDATASET])
REFERENCES [dbo].[BSH_DATASET] ([IDDATASET])
GO
ALTER TABLE [dbo].[BSH_IMGVER] WITH CHECK ADD CONSTRAINT [F080318150041281] FOREIGN KEY([IDVOLUME])
REFERENCES [dbo].[VOLUME] ([IDVOLUME])
I want to take distinct rows but since the relation is one to many the following query gives all the id fields that relate to an id image
Select DISTINCT
BSH_FLD1.IDFIELD as name,
'Dosje' as type,
'arkivuar' as 'ecm:currentLifeCycleState',
BSH_FLD1.IDFIELD as 'dc:title',
BSH_FLD1.IDFIELD,
BSH_FLD1.EC_NOP,
BSH_FLD1.EC_NOI,
BSH_FLD1.EC_NOA,
BSH_FLD1.INTESTIMI,
BSH_FLD1.KUTIA,
BSH_FLD1.DREJTORIA,
BSH_FLD1.DOSJA,
BSH_FLD1.VITI,
BSH_FLD1.AFATI,
CONVERT(VARCHAR(10), BSH_FLD1.FILLIMI,103) as FILLIMI,
CONVERT(VARCHAR(10),BSH_FLD1.FUNDI,103) as FUNDI,
BSH_FLD1.FAQE,
BSH_FLD1.FILMI,
BSH_FLD1.BLIP,
BSH_FLD1.DEPARTAMENTI,
BSH_FLD1.LLOJI_I_DOKUMENTIT,
BSH_FLD1.ADRESIMI,
BSH_FLD1.KLASIFIKIMI,
BSH_FLD1.KOMENTE,
BSH_FLD1.FRAKSION,
BSH_FLD1.OBJEKTI,
BSH_IMGVER.IDIMAGE,
BSH_IMGVER.VERSION,
BSH_IMGVER.IDDATASET,
BSH_IMGVER.IDVOLUME,
BSH_IMGVER.IMAGE as 'file:content',
BSH_IMGVER.CHECKEDOUT,
BSH_IMGVER.CHECKOUTBY,
CONVERT(VARCHAR(10),BSH_IMGVER.ADDDATE,103) as ADDDATE,
BSH_IMGVER.ADDBY,
BSH_IMGVER.ORGFNAME,
BSH_IMGVER.NROFPAGES
From BSH_FLDIMG1
JOIN BSH_FLD1 ON BSH_FLDIMG1.IDFIELD = BSH_FLD1.IDFIELD
JOIN BSH_IMGVER ON BSH_FLDIMG1.IDIMAGE = BSH_IMGVER.IDIMAGE
This brings me for example id field 1-idimage 1 and idfield 1-idimage 2
.I want only one row for one id field.
Now the result set is:
|name|type |.......|idImage|
|1 |Dosje|.......|1
|1 |Dosje|.......|2
|2 |Dosje|.......|3
|2 |Dosje|.......|4
|2 |Dosje|.......|5
I want to have the following :
|name|type |.......|idImage|
|1 |Dosje|.......|1
|2 |Dosje|.......|3
Can someone help me??
I have database with following tables
Login table:
CREATE TABLE [dbo].[Login]
(
[username] [nvarchar](100) NOT NULL,
[password] [nvarchar](50) NOT NULL,
[user_type] [nchar](10) NOT NULL,
[id] [int] IDENTITY(1,1) NOT NULL,
[isDelete] [bit] NOT NULL,
)
Test table:
CREATE TABLE [dbo].[Test]
(
[TestId] [int] IDENTITY(1,1) NOT NULL,
[TestName] [nvarchar](100) NOT NULL,
[UserId] [int] NOT NULL,
[isDelete] [bit] NOT NULL,
)
Questions table:
CREATE TABLE [dbo].[Questions]
(
[Qid] [int] IDENTITY(1,1) NOT NULL,
[Tid] [int] NOT NULL,
[Qtype] [int] NOT NULL,
[Question] [nvarchar](max) NOT NULL,
[isDelete] [bit] NULL,
)
Login.id is a foreign key and references Test.UserId
Test.TestId is foreign key and references Questions.Tid
My question is: I want to fetch Login.username, Test.TestName and the number of questions per test, e.g. I want all tests present and number of questions per test (even if 0).
I tried the following query
select
Test.TestId, Test.TestName, COUNT(Questions.Tid) as 'No.Of Questions'
from
Test, Questions
where
Test.TestId = Questions.Tid and
Questions.isDelete <> 'true'
group by
TestId, TestName
but this query only returns the tests for which at least single question is present in questions table.
I want all tests compulsory and then questions per test.
you need to use Left outer join
select T.TestId,T.TestName,COUNT(Q.Tid) as [No.Of Questions]
from Test t
Left Join Questions q
On Q.isDelete<>'true'
and T.TestId=Q.Tid
group by TestId,TestName
your current syntax works like Inner Join. Thats the reason you are getting tests which is not having any questions
I have a Test table
CREATE TABLE [dbo].[Test](
[TestId] [int] IDENTITY(1,1) NOT NULL,
[TestName] [nvarchar](50) NOT NULL,
[UserId] [int] NOT NULL,
[isDelete] [bit] NOT NULL,
and Questions table as
CREATE TABLE [dbo].[Questions](
[Qid] [int] IDENTITY(1,1) NOT NULL,
[Tid] [int] NOT NULL,
[Qtype] [int] NOT NULL,
[Question] [nvarchar](max) NOT NULL,
[isDelete] [bit] NULL,
Questions table stores all the questions for each test with Tid as foreign key.
I want to write a stored procedure to fetch TestName, TestId and number of questions in each test in a single stored procedure. But I am unable to get this.
You can write the stored procedure as:
CREATE PROCEDURE [dbo].[procGetNumberofQuestionsForTest]
AS
BEGIN
SELECT T.[TestId], T.[TestName], COUNT(Q.[Qid]) AS NumberOfQuestions
FROM [dbo].[Test] T
JOIN [dbo].[Questions] Q ON Q.Tid = T.TestId
GROUP BY T.[TestId], T.[TestName]
END
If you want to get the result for specific Test, then pass the parameter as #TestId INT and add the WHERE clause as WHERE T.[TestId] = #TestId before the GROUP BY.
Try this (table create, insert, proc creation and execution included);
CREATE TABLE [dbo].[Test](
[TestId] [int] IDENTITY(1,1) NOT NULL,
[TestName] [nvarchar](50) NOT NULL,
[UserId] [int] NOT NULL,
[isDelete] [bit] NOT NULL)
go
CREATE TABLE [dbo].[Questions](
[Qid] [int] IDENTITY(1,1) NOT NULL,
[Tid] [int] NOT NULL,
[Qtype] [int] NOT NULL,
[Question] [nvarchar](max) NOT NULL,
[isDelete] [bit] NULL
)
go
insert into [dbo].[Test]
values('test #1',1,0)
go
insert into [dbo].[Questions]
values(1,1,'what is life',0)
go
create proc dbo.MyInfo
as
select
t.TestName,
t.TestId,
[No Questions]=COUNT(q.Qid)
from
[dbo].[Test] t
inner join
[dbo].[Questions] q on t.TestId=q.Qid
group by
t.TestName,
t.TestId
go
exec dbo.MyInfo
go