Nested cursor, While Loop SQL - sql

I am trying to insert data into two tables(at one shot 100 to 150 rows on both tables). First Table Primary key have a reference with Second Table Foreign key.I Read that Cursor is having problem for ##Fetch_Status is global variable. Which is best way to loop and do data insertion in both tables Cursor or While Loop or any other.
CREATE TABLE Table1
(
FirstTablePK [int] NOT NULL, --Mannual Increment(Not Identity)
Description [varchar](100) NOT NULL,
CONSTRAINT PK_Table1 PRIMARY KEY CLUSTERED (FirstTablePK)
)
CREATE TABLE Table2
(
SecondTablePK [int] NOT NULL, --Mannual Increment(Not Identity)
FirstTablePK [int] NOT NULL, -- Foreign Key Reference with Table1
Description [varchar](100) NOT NULL,
CONSTRAINT PK_Table2 PRIMARY KEY CLUSTERED (SecondTablePK),
CONSTRAINT FK_Table1 FOREIGN KEY (FirstTablePK) REFERENCES Table1(FirstTablePK)
)
Thanks in Advance.
Hari

A cursor is not often used to look up foreign keys. It's faster and easier to use a set-based query:
insert into SaleOrder
(remarks, product_id, customer_id, ...)
select 'please deliver fast'
, (select id from Products where name = 'Car Oil')
, (select id from Customers where name = 'India Corp')
, ...

Related

creating tables in visual studio sql

i get this error when i execute
SQL71516 :: The referenced table '[dbo].[Stock]' contains no primary or candidate keys that match the referencing column list in the foreign key. If the referenced column is a computed column, it should be persisted.
CREATE TABLE [dbo].[Customer]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[FirstName] NCHAR(10) NOT NULL,
[LastName] NCHAR(10) NOT NULL,
[Email] NCHAR(10) NOT NULL UNIQUE,
[Mobile] NCHAR(10) NOT NULL
)
CREATE TABLE [dbo].[Stock]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[name] NCHAR(10) NOT NULL,
[price] INT NOT NULL,
CustomersID int NOT NULL,
FOREIGN KEY (CustomersID) REFERENCES Customer(Id)
ON DELETE CASCADE ON UPDATE CASCADE
)
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_price int NOT NULL,
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_price1] FOREIGN KEY ([Stock_price])
REFERENCES [Stock](price) ON DELETE CASCADE ON UPDATE CASCADE
)
You can only use columns that are uniquely indexed. The price column is not. However, I suspect that the foreign key that's giving you a hard time is actually wrong anyway. I also don't think you should have a CustomerId reference in your Stock table.
in fact, the basic standard database structure for a store is this:
Customer table
id, name [, other details]
Stock table
id, name, price [, other details]
Order table
id, customer id, order date [, other details]
Order details table
id, order id, item id, quantity, price [, other details]
This way, an order is related to a single customer, an can contain multiple items.
The price column in the order details table represents the item price at the date of the order - while the price column in the stock table represents the item's current price.
[Stock].[price] is not a key, that's why you can't define a foreign key on that column.
If 2 products (A and B) in table Stock have the same price, what would be the reference?
You can either set a key on this column, such as UNIQUE but this will prevent you to have differents prices in your table Stock.
I suggest you to use the [Stock].[Id] key as reference for your foreign key, such as :
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_id int NOT NULL, -- <--- changed column name
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_id1] FOREIGN KEY ([Stock_id]) -- <-- changed column name
REFERENCES [Stock](Id) ON DELETE CASCADE ON UPDATE CASCADE
-- ^--^------------------------------------- Notice this
);

Insert statement error

I have table dbo.Students_Old with columns :
Name(varchar), DocNum(int), Group(varchar), Form(varchar).
It have no primary key and I need to normalize this table. So I am going to make three tables:
dbo.Students(StudentId(int primary key), Name(varchar), Group(int fk),
Form(int fk),
dbo.Forms(FormId(int pk), FName(varchar)), dbo.Groups(GroupId(int pk),
GName(varchar)).
And also I need to fill all this tables with data from dbo.Students_Old. My code is:
CREATE TABLE dbo.Groups(GroupId int IDENTITY(1,1) PRIMARY KEY, GName nvarchar(10));
GO
INSERT INTO dbo.Groups(GName)
select Group
from dbo.Students_Old
group by Group
GO
CREATE TABLE dbo.Forms(FormId int IDENTITY(1,1) PRIMARY KEY, Form nvarchar(20));
INSERT INTO dbo.Forms(Form)
select Form
from dbo.Students_Old
group by Form
GO
CREATE TABLE dbo.Students (StudentId int PRIMARY KEY, Name nvarchar(50),
Form int NOT NULL,
Group int NOT NULL,
CONSTRAINT Form FOREIGN KEY(StudentId) REFERENCES dbo.Forms(FormId),
CONSTRAINT Grup FOREIGN KEY(StudentId) REFERENCES dbo.Groups(GroupId));
GO
INSERT INTO dbo.Students(StudentId, Name, Form, Group)
select DocNum, Name, f.FormId, g.GroupId
from dbo.Students_Old s
join dbo.Forms f on s.Form=f.Form
join dbo.Groups g on s.Group=g.GName
Also Students_Old.DocNum is unique.
Tables creates normaly, but on the insert statement i have an error:
The INSERT statement conflicted with the FOREIGN KEY constraint "Form". The conflict occurred in database "DBNames", table "dbo.Forms", column 'FormId'.
Help me please.
Execute the below query on a new database
CREATE TABLE dbo.Groups(GroupId int IDENTITY(1,1) PRIMARY KEY, GName nvarchar(10));
GO
INSERT INTO dbo.Groups(GName)
select Group
from dbo.Students_Old
group by Group
GO
CREATE TABLE dbo.Forms(FormId int IDENTITY(1,1) PRIMARY KEY, Form nvarchar(20));
INSERT INTO dbo.Forms(Form)
select Form
from dbo.Students_Old
group by Form
GO
CREATE TABLE dbo.Students (StudentId int PRIMARY KEY, Name nvarchar(50),
Form int NOT NULL,
[Group] int NOT NULL,
CONSTRAINT Form FOREIGN KEY(Form) REFERENCES dbo.Forms(FormId),
CONSTRAINT Grup FOREIGN KEY(Group) REFERENCES dbo.Groups(GroupId));
GO
INSERT INTO dbo.Students(StudentId, Name, Form, Group)
select DocNum, Name, f.FormId, g.GroupId
from dbo.Students_Old s
join dbo.Forms f on s.Form=f.Form
join dbo.Groups g on s.Group=g.GName
I've changed to following lines
CONSTRAINT Form FOREIGN KEY(Form) REFERENCES dbo.Forms(FormId),
CONSTRAINT Grup FOREIGN KEY([Group]) REFERENCES dbo.Groups(GroupId));
In your code the foreign key is made on StudentID column
Not sure if that is the case, since you get the FOREIGN KEY error, but try avoiding column names like GROUP or other reserved words. While you can avoid errors on table creation step, you can face serious problems during modifications/updates on such tables.
execute below query.
CREATE TABLE dbo.Groups(GroupId int IDENTITY(1,1) PRIMARY KEY, GName nvarchar(10));
GO
INSERT INTO dbo.Groups(GName)
select [Group]
from dbo.Students_Old
group by [Group]
GO
CREATE TABLE dbo.Forms(FormId int IDENTITY(1,1) PRIMARY KEY, Form nvarchar(20));
INSERT INTO dbo.Forms(Form)
select Form
from dbo.Students_Old
group by Form
GO
CREATE TABLE dbo.Students (StudentId int PRIMARY KEY, Name nvarchar(50),
Form int NOT NULL,
[Group] int NOT NULL,
CONSTRAINT Form FOREIGN KEY(StudentId) REFERENCES dbo.Forms(FormId),
CONSTRAINT Grup FOREIGN KEY(StudentId) REFERENCES dbo.Groups(GroupId));
GO
INSERT INTO dbo.Students(StudentId, Name, Form, [Group])
select DocNum, Name, f.FormId, g.GroupId
from dbo.Students_Old s
join dbo.Forms f on s.Form=f.Form
join dbo.Groups g on s.[Group]=g.GName

How to increment a primary key in an insert statement in SQL Server 2005

I need to write an insert statement into a table the columns looks like this
demandtypeid (PK, FK, int, not null)
characvalueid (PK, FK, int, not null)
percentage (int null)
lastuser (varchar(100), null)
lastedited (datetime, null)
Here is the INSERT statement. Notice the there is not values at the
value( , , 'Bob')
as I think that's where the auto-increment command should go
insert into tr_demandtypecharac(demandtypeID, characvalueid, lastuser)
values( , , 'Bob')
Please help with a simple little statement
I just want to know how to manually insert into this table
Here's my table structure:
CREATE TABLE [dbo].[tr_demandtypecharac](
[demandtypeid] [int] NOT NULL,
[characvalueid] [int] NOT NULL,
[percentage] [int] NULL,
[lastuser] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[lastedited] [datetime] NULL,
CONSTRAINT [PK_tr_dtc_pkey] PRIMARY KEY CLUSTERED
(
[demandtypeid] ASC,
[characvalueid] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[tr_demandtypecharac] WITH CHECK
ADD CONSTRAINT [FK_tr_dtc_cvid]
FOREIGN KEY([characvalueid]) REFERENCES [dbo].[tr_characvalue] ([characvalueid])
ALTER TABLE [dbo].[tr_demandtypecharac] WITH CHECK
ADD CONSTRAINT [FK_tr_dtc_dtid]
FOREIGN KEY([demandtypeid]) REFERENCES [dbo].[tr_demandtype] ([demandtypeid])
If you want an int column that is unique and autoincrementing, use the IDENTITY keyword:
CREATE TABLE new_employees
(
id_num int IDENTITY(1,1),
fname varchar (20),
minit char(1),
lname varchar(30)
)
Then when you insert into the table, do not insert anything for that column -- it will autoincrement itself.
Given the CREATE TABLE statement you posted, without auto-increment (aka identity) columns, you would insert providing all columns and values, like this:
insert into tr_demandtypecharac(
demandtypeid, characvalueid,
percentage, lastuser, lastedited)
values(2, 3, 80, 'Bob', '01/01/2012')
If, however, you do make them auto-increment by changing the CREATE TABLE to:
CREATE TABLE [dbo].[tr_demandtypecharac](
[demandtypeid] [int] NOT NULL IDENTITY(1,1),
[characvalueid] [int] NOT NULL IDENTITY(1,1),
[percentage] [int] NULL,
[lastuser] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[lastedited] [datetime] NULL,
CONSTRAINT [PK_tr_dtc_pkey] PRIMARY KEY CLUSTERED
(
[demandtypeid] ASC,
[characvalueid] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
)
Then you would insert providing all non-identity (non-autoincrement) columns like this:
insert into tr_demandtypecharac(
percentage, lastuser,
lastedited)
values(80, 'Bob', '01/01/2012')
However, it is not common to have more than one column as an identity (autoincrement) column, and generally, this column is the only PRIMARY KEY column.
If a column is an autoincement column (which is different than a primary key column) then you omit the column in your insert statement and it will be filled in.
INSERT INTO tr_demandtypecharac (lastuser) VALUES ('Bob')
I had a similar issue and needed to update a purchased database with a set of records. My solution was to find the highest key used so far, then use that as the base of my insert. The core of it was ROWNUMBER() OVER(ORDER BY PART_CODE).
The key is the "recnum" field in the inadjinf table. I determined that the highest current key was 675400 and updated my query to be:
insert into inadjinf (recnum, user_id, adj_type, adj_status, trans_date, part_code, lotqty, uom, cost_ctr, lot, location, to_cost_ctr, to_location, rec_status, to_part_grade, to_rec_status, remarks1, uom_conv)
select ROW_NUMBER() OVER(ORDER BY INVDET.PART_CODE) + 675400 as recnum, 'CHRSTR' as user_id, 'M' as adj_type, 'O' as adj_status, '2020-10-23' as trans_date, invdet.part_code, sum(lotqty) as lotqty, uom,
cost_ctr, lot, location, 'NS' as to_cost_ctr, '500A' as to_location, rec_status, 'Q' as to_part_grade, 'H' as to_rec_status, 'NS Scrap Request from MSobers 10/21/2020' as remarks1, '1' as uom_conv
from invdet
inner join partmstr on invdet.part_code = partmstr.part_code
where
invdet.part_code In
(
'86038',
'1271',
'VM-0021',
'CO-0107',
...
'FO-0391',
'FO-0376'
)
and lot not in (select lot from inadjinf where trans_date = '2020-10-23' and user_id = 'CHRSTR')
group by invdet.part_code, uom, cost_ctr, lot, location, rec_status
My output started with 675401 and went up from there. In the end, I updated the system's internal "next id field" table record.
You should not use int as primary keys... heres a article about it: http://techtrainedmonkey.com/2012/07/30/why-integers-are-lousy-primary-keys/
but if you do... set the field as identity and Sql Server will do it for you... check it out: http://msdn.microsoft.com/en-us/library/ms186775.aspx

SQL Server - foreign key reference error

I have two tables, Table_1 with 4 columns (3 primary key) and Table_2 with 2 column. When I try to create a foreign key constraint in Table_2, I am getting this error:
Here are the definitions of my tables:
Table_1
CREATE TABLE [dbo].[Table_1]
(
[Field_1] [tinyint] NOT NULL,
[Field_2] [tinyint] NOT NULL,
[Field_3] [tinyint] NOT NULL,
[Field_4] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED
(
[Field_1] ASC,
[Field_2] ASC,
[Field_3] ASC
)
Table_2
CREATE TABLE [dbo].[Table_2]
(
[Field_1] [tinyint] NOT NULL,
[Field_2] [tinyint] NOT NULL
) ON [PRIMARY]
Do you have any idea on how to solve this? Thanks -
The primary key of Table_1 is all three of Field_1, Field_2 and Field_3. In order to reference a key in another table, you have to reference all of the columns in that key - so you would need to add Field_2 and Field_3 to Table_2, and have all three columns included when you attempt to create the foreign key constraint.
Alternatively, if Field_1, by itself, is a key for Table_1, then declare it as such, either by redefining the primary key, or adding a UNIQUE constraint on just Field_1 to Table_1. You would then be able to create the foreign key you're attempting to.

SQL Table Datastructure, is this wrong? Using CASCADING Delete

Here are the 3 tables I am having problems with:
Table: Opportunities - Holds various opportunity(job) descriptions
Table: Opportunities_Applicants - Holds various applicants applying for opportunities. 1 Applicant can only apply for 1 opportunity, however 1 opportunity can have many applicants
Table: Opportunities_Category - Holds category name and type. 1 Category can relate to many Opportunities.
I am trying to perform a CASCADING Delete when a Opportunity Category is deleted, it will delete corresponding Opportunities and Applicants for those Opportunities.
Is this structure appropriate or should I setup database differently? How should my table relationships be setup in order for the CASCADING Delete to work when a Opportunity Category is deleted?
Should I even be using CASCADING Delete?
create table Opportunities_Category
(
CategoryID int identity(1,1) not null
constraint PK_CategoryID primary key clustered,
[Name] varchar(150) not null,
[Type] varchar(100) not null --Pay, Volunteer, Volunteer Yearly
)
create table Opportunities
(
OpportunityID int identity(1,1) not null
constraint PK_OpportunityID primary key clustered,
CategoryID int not null
constraint FK_CategoryID foreign key references Opportunities_Category(CategoryID) ON DELETE CASCADE,
Title varchar(300) not null,
PostingDate datetime not null,
ClosingDate datetime not null,
Duration varchar(150) not null, --Part Time, Full Time, Seasonal, Contract
Compensation varchar(150) not null, --Hourly, Volunteer, Salary
[Description] varchar(5000) not null,
Qualifications varchar(5000) not null,
Show int not null
)
create table Opportunities_Applicant
(
ApplicantID int identity(1,1) not null
constraint PK_ApplicantID primary key clustered,
OpportunityID int not null
constraint FK_OpportunityID foreign key references Opportunities(OpportunityID) ON DELETE CASCADE,
[First] varchar(150) not null,
[Last] varchar(150) not null,
Phone varchar(20) not null,
Cell varchar(20) not null,
EMail varchar(200) not null,
CoverLetterResume varchar(300) null,
[Timestamp] datetime not null
)
It turns out that my tables are setup properly:
Yesterday, i had been trying to do: DELETE FROM Opportunities WHERE CategoryID = #CategoryID. This was only deleting the records from Opportunities and Opportunities_Applicants.
Today, i changed to: DELETE FROM Opportunities_Categoies WHERE CategoryID = #CategoryID and all 3 tables are deleting their corresponding records!
ALTER TABLE [dbo].[Opportunities] WITH CHECK ADD CONSTRAINT [FK_OpportunitiesCategory_Opportunities] FOREIGN KEY([CategoryID])
REFERENCES [dbo].[Opportunities_Category] ([CategoryID])
ON DELETE CASCADE
GO
Good Luck...