How to put FK into another table using Stored Procedure - c#

I have one login form like :
Username: Ashish
Password: Pass
Contact no: 1234567890
State: Maharashtra
Having two tables :
create table DGRegion
(DG_Regionno Int Identity (1,1) NOT Null constraint pk1 Primary Key,
DG_Username varchar(50),
DG_Password varchar(50),
DG_Contactno int ,
DG_StateNo int References DGState(DG_stateno))
Create table DGState
(DG_stateno Int Identity (1,1) NOT Null constraint pk Primary Key ,
DG_State varchar (50))
Now how can I create one stored procedure P which will enter values into DGRegion and DGState tables?
After click on submit I'm using asp.net.
Problem is: I can enter values into DGRegion table directly but how can I enter reference of state into table DGState?

Try something like this:
CREATE PROCEDURE dbo.EnterLoginData(#Username VARCHAR(50), #Password VARCHAR(50),
#ContactNo INT, #StateName VARCHAR(50))
AS BEGIN
DECLARE #StateID INT
-- check if state already exists
IF EXISTS(SELECT * FROM dbo.DGState WHERE DG_State = #StateName)
-- if it exists - retrieve the DG_StateNo
SELECT #StateID = DG_StateNo
FROM dbo.DGState
WHERE DG_State = #StateName
ELSE BEGIN
-- if it doesn't exists - insert new row
INSERT INTO dbo.DG_State(DG_State) VALUES(#StateName);
-- get the newly inserted row's ID using SCOPE_IDENTITY()
SELECT #StateID = SCOPE_IDENTITY()
END
INSERT INTO
dbo.DGRegion(DG_Username, DG_Password, DG_ContactID, DG_StateNo)
VALUES(#Username, #Password, #ContactNo, #StateID)
END

In the sp:
check if the state is in the state table
if not, put it into the state table
get the id (DG_stateno) of the state table, put in variable
execute your insert

Related

How can i get the row id that inserted via stored procedure?

Model model=new Model();
model.id=0;
model.name="";
model.surname="";
db.Model.Add(model);
db.SaveChanges();
int id_returned=model.id;
This block gives me the id field of the inserted row.
But i use stored procedure for this insert process.
Model model=new Model();
model.id=0;
model.name="";
model.surname="";
int returned_id2=db.Sp_Model_insert(model.name, model.surname);
this block inserts the row. returned_id2 returns -1.
How can i get the row id that inserted via Sp ?
Here is my Stored Procedure:
USE [KayaShop]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [KS_ACCOUNTS].[SP_AccountModules_Insert](
#Area nvarchar(50),
#Controller nvarchar(50),
#Action nvarchar(50),
#SubAction nvarchar(50),
#Name nvarchar(50),
#TopName nvarchar(50),
#Level int,
#Visible int,
#Clickable int,
#HomePage int,
#Icon nvarchar(20),
#Status int
)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO [KS_ACCOUNTS].[AccountModules]
([Area]
,[Controller]
,[Action]
,[SubAction]
,[Name]
,[TopName]
,[Level]
,[Visible]
,[Clickable]
,[HomePage]
,[Icon]
,[Status])
VALUES
(#Area,
#Controller,
#Action,
#SubAction,
#Name,
#TopName,
#Level,
#Visible,
#Clickable,
#HomePage,
#Icon,
#Status)
END
SELECT SCOPE_IDENTITY()
Add this after the insert query in your stored procedure
Multiple ways:
SCOPE_IDENTITY() - https://msdn.microsoft.com/en-us/library/ms190315.aspx - Returns the last single IDENTITY value in the current session's current scope.
##IDENTITY - https://msdn.microsoft.com/en-us/library/ms187342.aspx - Returns the last single IDENTITY value in the current session (regardless of scope).
INSERT INTO ... VALUES ... OUTPUT - https://msdn.microsoft.com/en-us/library/ms177564.aspx - outputs all inserted values, including IDENTITY values, this is the only way to retrieve IDENTITY values when your INSERT statement will insert multiple rows.
As your stored procedure only seems to insert a single row, you should be fine with SCOPE_IDENTITY.
Note that if all your stored procedure does is INSERT you probably don't need a stored procedure, your database client code should perform the INSERT directly.
Note that you should not use the RETURN keyword to return the IDENTITY value to the caller, you should use output parameters - a stored procedure's return-value is intended to convey status information and it is restricted to just an int value (e.g. return 0 for success).
I added these lines to the end of my sp:
SELECT #Id =SCOPE_IDENTITY()
RETURN
and at my code side:
int Id = 0;
ObjectParameter prm = new ObjectParameter("Id", typeof(int));
DB.SP_AccountModules_Insert(DTO.Area, DTO.Controller, DTO.Action, DTO.SubAction, DTO.Name, DTO.TopName, DTO.Level, DTO.Visible, DTO.Clickable, DTO.HomePage, DTO.Icon, DTO.Status, prm);
Id = Convert.ToInt32(prm.Value);
return Id;
i send and out parameter from my code to my sp, then i assign the last inserted id to my parameter and return it to my code. thats it.
Thank you for all help.

Calling stored procedure from another stored procedure with parameters

I have a stored procedure with takes 2 parameters (StudentID and CurrentSmester) as input and return me table with fields :
Course Code
Update Type
Update Id
This stored procedure is created by another team in my office. I can not modify it but at the same point I want to use it in my Webservice (which I am building for android) to make sure data remains consistent.
My requirement is to get :
Course Code
Update Type
Update Id
Course Title
Can I create another store procedure which will call that store procedure with parameters as I mentioned, make a join with course table to get course title too.
Is this possible ? If yes can you please guide me through its implementation.
Thanking You and Happy New Year !!
Create a new stored procedure , insert the results coming back from your existing stored procedure into a temp table, join your Course table with that temp table and you are good to go ,
something like this.....
CREATE PROCEDURE usp_NewProc
#StudentID INT ,
#CurrentSmester INT
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#temp', 'U') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
CourseCode [DataType],
UpdateType [DataType],
Update Id [DataType]
)
INSERT INTO #temp
EXEC existsting_proc #StudentID , #CurrentSmester
SELECT t.* , C.CourseTitle
FROM #temp t INNER JOIN CourseTable C on <join Condition>
IF OBJECT_ID('tempdb..#temp', 'U') IS NOT NULL
DROP TABLE #temp
END
You can insert the results from the STORED PROCEDURE into a temp table (table variable or temp table) and them select from that table and join onto the Courses table to retrieve the title.
SQL Fiddle DEMO
Example code
CREATE TABLE Courses(
CourseCode VARCHAR(50),
CourseName VARCHAR(250)
);
INSERT INTO Courses VALUES ('A','AA'), ('B','BB');
CREATE PROCEDURE OtherTeamsSP(
#StudentID INT,
#CurrentSmester INT
)
AS
SELECT 'A' CourseCode,
'FOO' UpdateType,
1 UpdateId;
CREATE PROCEDURE MyProcedure(
#StudentID INT,
#CurrentSmester INT
)
AS
CREATE TABLE #SPOutput(
CourseCode VARCHAR(50),
UpdateType VARCHAR(50),
UpdateId INT
)
INSERT INTO #SPOutput
EXEC OtherTeamsSP #StudentID, #CurrentSmester
SELECT *
FROM #SPOutput s INNER JOIN
Courses c ON s.CourseCode = c.CourseCode
DROP TABLE #SPOutput
Calling the new SP
EXEC MyProcedure 1,2
-- First Stored Procedure
CREATE PROCEDURE FirstSP
#MyFirstParam INT
AS
DECLARE #MyFirstParamValue INT
SELECT #MyFirstParamValue = #MyFirstParam * #MyFirstParam
RETURN (#MyFirstParamValue)
GO
-- Second Stored Procedure
CREATE PROCEDURE SecondSP
#SecondParam INT
AS
DECLARE #SecondParamValue INT
SELECT #SecondParamValue = #SecondParam * #SecondParam
RETURN (#SecondParamValue)
GO
-- Pass One Stored Procedure's Result as Another Stored Procedure's Parameter
DECLARE #FirstValue INT, #SeondValue INT
-- First SP
EXEC #FirstValue = FirstSP 5
-- Second SP
EXEC #SeondValue = SecondSP #FirstValue
SELECT #SeondValue SecondSP
GO
-- Clean up
DROP PROCEDURE FirstSP
DROP PROCEDURE SecondSP
GO

InvalidOperationException on EF

I'm using WPF MVVM Pettern and
I Have a simple table on SQL Server 2012 which its ID(key) column is computed in an StoredProcedure, called PersonInsert: (This is simplified, but what is computed is more complex than this, anyway it's an int at last)
USE [Guard]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[PersonInsert]
#FName NVARCHAR(50) ,
#LName NVARCHAR(50) ,
#ID INT = NULL OUTPUT
AS
BEGIN
BEGIN TRY
SELECT #ID = ISNULL(MAX(ID), 0) + 1
FROM dbo.Person
INSERT INTO [dbo].[Person]
( [ID] ,
[FName] ,
[LName]
)
VALUES ( #ID ,
#FName ,
#LName
)
END TRY
BEGIN CATCH
DECLARE #ErrMsg NVARCHAR(MAX) ,
#ErrSvr INT ,
#ErrStt INT
SELECT #ErrMsg = ERROR_MESSAGE() + '|' + ERROR_PROCEDURE() + '|'
+ CAST(ERROR_LINE() AS NVARCHAR(5)) ,
#ErrSvr = ERROR_SEVERITY() ,
#ErrStt = ERROR_STATE()
RAISERROR (#ErrMsg, #ErrSvr, #ErrStt)
END CATCH
END
GO
In the .net side, I use EF 6.1 Code-First to handle data and mapped to SPs so I have OnModelCreating like this:
modelBuilder.Entity(Of Person)().MapToStoredProcedures(
Sub(x)
x.Insert(Function(e) e.HasName("[dbo].[PersonInsert]"))
x.Update(Function(e) e.HasName("[dbo].[PersonUpdate]"))
x.Delete(Function(e) e.HasName("[dbo].[PersonDelete]"))
End Sub)
And My Model is:
<Table("Person")> _
Partial Public Class Person
<DatabaseGenerated(DatabaseGeneratedOption.None), Key> _
Public Property ID As Integer
Public Property FName As String
Public Property LName as String
End Class
Now the strange thing is, when I try to Insert Data (Adding New Person) at first time, the db.SaveChanged() works great, but for second time it throws InvalidOperation exception with a message:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Saving or accepting changes failed because more than one entity of type 'Shoniz.Guard.WPFGuardApplication.Person' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration.
He is right! the data is comitted successfully! and I'm right too, because my ID(key) column is computed right and it's completely unique. Either I have used the DatabaseGeneratedAttribute with none value on ID, but the result is the same :(
Even when I re-query the db to check about duplicate keys, I find NOTHING!
Why this exception is thrown?
How can I prevent that?
Is there anyway to Ignore the changes after db.SaveChanges()?
First of all change DatabaseGeneratedOption.None to DatabaseGeneratedOption.Indetity
and finally change stored procedure to this:
BEGIN TRY
SELECT #ID = ISNULL(MAX(ID), 0) + 1
FROM dbo.Person
INSERT INTO [dbo].[Person]
( [ID] ,
[FName] ,
[LName]
)
VALUES ( #ID ,
#FName ,
#LName
)
--You have to tell EF this is returned Id of inserted person
SELECT #ID as ID
END TRY

Inserting Foreign key using primary key in asp.net

I am making a form in asp using C# and my task is to make a course and packages detail and insert the , i have make three tables one is Course which contain Id(pk) and Course-name, packages table contain Id(pk) and pkg-name and other table is Pkg-detail which contain Pkg-id(pk) and it is foreign key for Id in packages table and other attribute is course-id it is foreign key for course(ID) and my task is when i select pkg-name from drop down and course from check box from asp form that particular Id for pkg-name and Id for Course-name will insert in third table pkg-detail as i am new i have searched lot but cannot find related answer.
SqlCommand cmm = new SqlCommand("Pkc", con);
cmm.CommandType = CommandType.StoredProcedure;
cmm.Parameters.AddWithValue("#pname", drop1.SelectedValue);
cmm.Parameters.AddWithValue("#course", check1.SelectedValue);
con.Open();
cmm.ExecuteNonQuery();
con.Close();
CREATE PROCEDURE [dbo].[Pkc]
#course nvarchar(50),
#pname nvarchar(50)
AS
begin
insert into Pkg(CourseId)values((select Id from Courses where CourseName=#course));
insert into Pkg(PkgId) values ((select Id from PKgCode where PkgName=#pname))
end
You didn't mentioned your problem, but from your text it seems that you want to pass courceID and PackageID into your StoredProc, your code has a problem, since dropdown.SelectedValue is string by AddWithValue you will add two string parameter while I think they should be integer. So cast them as int or use other method that accepts type of parameter.
Edit
Base on comments it seems that your procedure should be like this:
CREATE PROCEDURE [dbo].[Pkc] #course nvarchar(50), #pname nvarchar(50)
AS
begin
declare #courceID int
declare #pkgID int
select #courceID = Id from Courses where CourseName=#course
select #pkgID = Id from PKgCode where PkgName=#pname
insert into Pkg-Detail(CourseId,PkgId) values(#courceID, #pkgID)
end

Issue with newid() after dropping table constraints using t-sql

There is a scenario where I have to drop primary key on a existing table and then insert a record into it. The table has a column called GUID as shown below
Create Table TEST_TABLE_VALUE (
TEST_TABLE_ID int Identity(1,1),
TEST_TABLE_VALUE int,
GUID uniqueidentifier Not Null Default newid(),
Primary Key (TEST_TABLE_ID, TEST_TABLE_VALUE)
)
Dropped the constraints using below code
Declare #TableName nvarchar(100)
Declare #TableId int
Declare #ConstraintName varchar(120)
Declare #IndexName varchar(120)
Declare #Command varchar(256)
Set #TableName = 'TEST_TABLE_VALUE'
Select #TableId = id From sysobjects Where [type]='U' and [name]=#TableName
Declare ConstraintDropCursor Cursor Local Fast_Forward
For Select name from sysobjects where (type='K' Or type='D' or type='F' or type='C') and parent_obj = #TableId
For Read Only
Open ConstraintDropCursor
Fetch Next From ConstraintDropCursor Into #ConstraintName
While ##Fetch_Status != -1
Begin
Set #Command = 'Alter Table dbo.' + #TableName + ' Drop Constraint ' + #ConstraintName
exec(#Command)
Fetch Next From ConstraintDropCursor Into #ConstraintName
End
Close ConstraintDropCursor
DeAllocate ConstraintDropCursor
After dropping the constraints when I tried to insert data into the table
Insert Into TEST_TABLE_VALUE (TEST_TABLE_VALUE) Values(1)
but got the below error:
Cannot insert the value NULL into column 'GUID', table 'CustApp1.dbo.TEST_TABLE_VALUE1'; column does not allow nulls. INSERT fails.
How can I solve this issue?
You have dropped the default for GUID column and it is not nullable column.Thus it is causing the issue. In case you want to insert lots of data and do not want constraint for maybe perf reasons. Then atleast do not drop the defaults for not nullable columns.
Well if you drop the default constraint you end up with
Create Table TEST_TABLE_VALUE (
TEST_TABLE_ID int Identity(1,1),
TEST_TABLE_VALUE int,
GUID uniqueidentifier Not Null,
Primary Key (TEST_TABLE_ID, TEST_TABLE_VALUE)
)
so if you wish to continue down this path you either have to provide a value for the GUID column
or also do
ALTER TABLE TEST_TABLE_VALUE ALTER COLUMN GUID uniqueidentifier NULL
to allow nulls.

Categories

Resources