I have the following two tables (only relevant key columns shown)
CREATE TABLE [dbo].[Jobs](
[ID] [int] IDENTITY(1,1) NOT NULL,
[JobNo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Jobs] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Items](
[JobID] [int] NOT NULL,
[BarcodeNo] [nvarchar](50) NOT NULL,
[SerialNo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Items_1] PRIMARY KEY CLUSTERED
(
[JobID] ASC,
[BarcodeNo] ASC,
[SerialNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I need to make sure that when an item is entered, the JobID matches an ID in the Jobs table. It seems, I can't use a FK because the PK in the items table is a composite key of 3 columns.
TIA
Mark
What kind of constraint can I use for this?
A foreign key works fine.
There's no problem with having the single column [dbo].[Items].[JobID] reference the PK of jobs.
CREATE TABLE [dbo].[Jobs]
(
[ID] [INT] IDENTITY(1, 1) NOT NULL,
[JobNo] [NVARCHAR](50) NOT NULL,
CONSTRAINT [PK_Jobs] PRIMARY KEY CLUSTERED ( [ID] ASC )
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
CREATE TABLE [dbo].[Items]
(
[JobID] [INT] NOT NULL REFERENCES [dbo].[Jobs]([ID]), /*<-- FK declaration*/
[BarcodeNo] [NVARCHAR](50) NOT NULL,
[SerialNo] [NVARCHAR](50) NOT NULL,
CONSTRAINT [PK_Items_1] PRIMARY KEY CLUSTERED ( [JobID] ASC, [BarcodeNo] ASC, [SerialNo] ASC )
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
Related
This question already has answers here:
How to insert a row into another table using last inserted ID?
(4 answers)
Closed 4 months ago.
I have a table 1 with an auto-generated primary key in SQL Server. I have a second table 2 where the auto-generated value from table 1 is a foreign key in table 2.
How can I write a query where I can INSERT into table 2, including the auto-generated value from table 1.
Preferably this would also work in a stored procedure.
Generate scripts:
CREATE TABLE [dbo].[POSTADRESSE](
[AdresseID] [int] IDENTITY(1,1) NOT NULL,
[GateNavn] [varchar](50) NULL,
[GateNR] [varchar](10) NULL,
[PostNR] [int] NULL,
[PostSted] [varchar](30) NULL,
CONSTRAINT [XPKPOSTADRESSE] PRIMARY KEY CLUSTERED
(
[AdresseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[KUNDE](
[TelefonNR] [varchar](15) NOT NULL,
[AdresseID] [int] NOT NULL,
[Epost] [varchar](320) NULL,
[Fornavn] [varchar](100) NULL,
[Etternavn] [varchar](100) NULL,
[Passord] [varchar](69) NULL,
CONSTRAINT [XPKKUNDE] PRIMARY KEY CLUSTERED
(
[TelefonNR] ASC,
[AdresseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
This is what I've tried:
INSERT INTO POSTADRESSE(GateNavn, GateNR, PostNR, PostSted)
VALUES ('Storgt', 3, 3901, 'Porsgrunn')
INSERT INTO KUNDE(TelefonNR, AdresseID, Epost, Fornavn, Etternavn, Passord)
VALUES (
47843329,
(SELECT POSTADRESSE.AdresseID FROM POSTADRESSE WHERE POSTADRESSE.GateNavn = 'Storgt'),
'hej#hotmail.se',
'Anton',
'Johanson',
'123abc'
);
Hi #VaBraAnton see this answer will help.
Declare #Identity as int
INSERT INTO POSTADRESSE(GateNavn, GateNR, PostNR, PostSted)
VALUES ('Storgt', 3, 3901, 'Porsgrunn')
Select #Identity=SCOPE_IDENTITY();
INSERT INTO KUNDE(TelefonNR, AdresseID, Epost, Fornavn, Etternavn, Passord)
VALUES (
47843329,
#Identity,
'hej#hotmail.se',
'Anton',
'Johanson',
'123abc'
);
see screen shot
Why would deleting 2 rows using IN() on a child table create a hash match of 197 million rows, this query times out in the app, but deleting 1 row using = or IN() works fine and completes instantly?
Exec plans and queries:
DELETE FROM dbo.ClientDepartmentContact WHERE ClientDepartmentContactId IN (12126,12127)
https://www.brentozar.com/pastetheplan/?id=rkKueM6HS
DELETE FROM dbo.ClientDepartmentContact WHERE ClientDepartmentContactId = 12126
https://www.brentozar.com/pastetheplan/?id=Sku2lGaBr
The primary/foreign keys relationship are not set to to cascade.
DDLs:
CREATE TABLE [dbo].[ClientDepartmentContact](
[ClientDepartmentContactId] [int] IDENTITY(1,1) NOT NULL,
[ClientId] [int] NOT NULL,
[DepartmentId] [smallint] NOT NULL,
[DispatchContactId] [int] NOT NULL,
[DispatchType] [char](1) NOT NULL,
[DispatchContactType] [char](1) NOT NULL,
CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Index
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ClientDepartmentContact](
[ClientDepartmentContactId] [int] IDENTITY(1,1) NOT NULL,
[ClientId] [int] NOT NULL,
[DepartmentId] [smallint] NOT NULL,
[DispatchContactId] [int] NOT NULL,
[DispatchType] [char](1) NOT NULL,
[DispatchContactType] [char](1) NOT NULL,
CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Index
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [PK_ClientDepartmentContact] PRIMARY KEY CLUSTERED
(
[ClientDepartmentContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ClientDepartmentContact] ADD CONSTRAINT [UK_ClientDepartmentContact] UNIQUE NONCLUSTERED
(
[ClientId] ASC,
[DepartmentId] ASC,
[DispatchContactId] ASC,
[DispatchType] ASC,
[DispatchContactType] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE TABLE [dbo].[DispatchContact](
[DispatchContactId] [int] IDENTITY(1,1) NOT NULL,
[Email] [varchar](254) NOT NULL,
CONSTRAINT [PK_DispatchContact] PRIMARY KEY CLUSTERED
(
[DispatchContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_ContactAddress_Email] ON [dbo].[DispatchContact]
(
[Email] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[DispatchContact] ADD CONSTRAINT [PK_DispatchContact] PRIMARY KEY CLUSTERED
(
[DispatchContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SQL version 2012 standard, all stats are up to date.
Before asking for help, i have restored to the DB to a 2014 and 2017 (both standard) dev instance and cant recreate the exec plan, the queries exec instantly on those. The plan for the 2017 is:
https://www.brentozar.com/pastetheplan/?id=BJdpX76rH
Stats are updated via a maintenance job nightly, but I did update all stats while investigating the issue. I have tried adding index's using SentryOnes Plan explorer Index analysis tool to no avail.
ps Thanks for your help
I've been tasked with creating a generic Trigger(one that will work on all tabled in my database) that will will fire on Insert, Delete, and Update to capture changes done on a table.
I have 2 new tables a Master Table...
CREATE TABLE [dbo].[DATA_HIL_Master](
[MasterId] [int] IDENTITY(1,1) NOT NULL,
[ReferenceTable] [nvarchar](100) NULL,
[ReferenceId] [int] NULL,
[OperationType] [smallint] NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL, PRIMARY KEY CLUSTERED (
[MasterId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS
= ON) ON [PRIMARY]
) ON [PRIMARY] GO
And then a Detail table...
CREATE TABLE [dbo].[DATA_HIL_Detail](
[DetailId] [int] IDENTITY(1,1) NOT NULL,
[MasterId] [int] NOT NULL,
[ColumnName] [nvarchar](100) NULL,
[OriginalValue] [nvarchar](max) NULL,
[ModifiedValue] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED (
[DetailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
My trigger needs to be able to update these tables with the correct information for that update and than table. For Instance I have another table..
CREATE TABLE [dbo].[CNF_Tax2Package](
[Tax2PackageId] [int] IDENTITY(1,1) NOT NULL,
[TaxPackageId] [int] NOT NULL,
[TaxId] [int] NOT NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL,
PRIMARY KEY CLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
EveryTime a record is change in this CNF_Tax2Package table I need to up the History tables with information
I do the following UPdate statement
Update CNF_Tax2Package
set TaxPackageid = 1,
Last_UserID_Log = 1098,
Last_WorkstationID_Log = 77,
Last_DateTime_Log = Getdate()
where Tax2PackageID = 2]
I would insert into the DATA_HIL_Master a row with the following information
[MasterId] = (NEWMasterID) [ReferenceTable] = 'CNF_Tax2Package' [ReferenceId] = 2 ---This is the primary Key of the
---table updated. [OperationType] = 'Update' [Last_UserId_Log] = 1098 [Last_WorkstationId_Log] = 77 [Last_DateTime_Log] getdate()
I would then insert into the DATA_HIL_Detail the following rows.
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'TaxPackageid' [OriginalValue] = '19' [ModifiedValue] = '1'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_UserID_Log' [OriginalValue] = '1954' [ModifiedValue] = '1098'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_WorkstationId_Log' [OriginalValue] = '55' [ModifiedValue] = '77'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_DateTime_Log' [OriginalValue] = '2018-08-18 [ModifiedValue] = getdate()
Understanding that the trigger must be generic enough to handle all tables in my database with different columns, different primary Keys
I am a beginner in SQL,
I have a table with GroupRole column and Age column.
CREATE TABLE [Persons](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[FullName] [varchar](70) NULL,
[Age] [int] NULL,
[GroupRole ] [varchar](30) NULL
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
I want to limit the value range that can be placed in an age column lower 30
and GroupRole column equal 'Admin'.
I do not want to do this in the c# code.
How can I do it?
this have easy way:
ALTER TABLE Persons
ADD CONSTRAINT CHK_PersonAge CHECK (Age>=30 AND GroupRole ='Admin');
You need to use Check Constraints. They are part of your table's metadata and define conditions to be checked every time, when the data is modified or inserted in the table. If these conditions are not met, the DML operation will fail with an error.
You need to modify your CREATE TABLE statement as follows:
CREATE TABLE [Persons](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[FullName] [varchar](70) NULL,
[Age] [int] NULL CONSTRAINT CHK_Age CHECK ([Age] < 30),
[GroupRole] [varchar](30) NULL CONSTRAINT CHK_GroupRole CHECK ([GroupRole] in ('Admin'))
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
I need to create a stored procedure transaction that will pull data from two tables and create a random integer to populate a third table (dbo.patient_address).
I want the following, but I am having a hard time understanding how to script this as a stored procedure.
dbo.address AddressID = dbo.patient_address AddressID,
dbo.patient PatientID = dbo.patient_address PatientID,
RAND is an integer between 1-3 (see dbo.addresstype) = dbo.patient_address AddressTypeID
Below are create statements of all of these tables.
ADDRESS TABLE - 30000 rows in place (complete data set)
CREATE TABLE [dbo].[ADDRESS](
[AddressID] [int] NOT NULL,
[StreetAddress] [varchar](50) NULL,
[City] [varchar](50) NULL,
[State] [varchar](50) NULL,
[PostalCode] [varchar](50) NULL,
CONSTRAINT [ADDRESS_PK] PRIMARY KEY CLUSTERED
(
[AddressID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
PATIENT TABLE - 30000 rows in place (complete data set)
CREATE TABLE [dbo].[PATIENT](
[PatientID] [int] NOT NULL,
[PatientFName] [varchar](50) NOT NULL,
[PatientLName] [varchar](50) NOT NULL,
[GenderID] [int] NOT NULL,
[DateOfBirth] [date] NOT NULL,
CONSTRAINT [PATIENT_PK] PRIMARY KEY CLUSTERED
(
[PatientID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ADDRESS TYPE - 3 choices (home, billing, work) – integer between 1 - 3
CREATE TABLE [dbo].[ADDRESS_TYPE](
[AddressTypeID] [int] NOT NULL,
[AddressTypeName] [varchar](10) NOT NULL,
[AddressTypeDescr] [varchar](10) NULL,
CONSTRAINT [ADDRESS_TYPE_PK] PRIMARY KEY CLUSTERED
(
[AddressTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[ADDRESS_TYPE]
([AddressTypeID],[AddressTypeName],[AddressTypeDescr])
Values ('1','Home','Home'), ('2','Bill','Billing'), ('3','Work','Work')
This is the final table that I want to populate from all of the above tables using a stored procedure transaction.
CREATE TABLE [dbo].[PATIENT_ADDRESS](
[PatientID] [int] NOT NULL,
[AddressID] [int] NOT NULL,
[AddressTypeID] [int] NULL,
CONSTRAINT [PATIENT_ADDRESS_PK] PRIMARY KEY CLUSTERED
(
[PatientID] ASC,
[AddressID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Try this:
INSERT INTO PATIENT_ADDRESS
SELECT PatientID, AddressID,
CONVERT(INT,(ABS(CHECKSUM(NEWID())/2148000000.))*3)+1 AS AddressTypeID
FROM (
SELECT PatientID, ROW_NUMBER() OVER (ORDER BY PatientID) AS RowNum
FROM dbo.PATIENT
) x
INNER JOIN (
SELECT AddressID, ROW_NUMBER() OVER (ORDER BY AddressID) AS RowNum
FROM dbo.ADDRESS
) y ON x.RowNum = y.RowNum