problem with sql table updation - asp.net

I have 2 tables
CREATE TABLE PODRAS_MS.tbl_FieldWorkers
(
[FWInsOnServerID] INT NOT NULL IDENTITY(1,1),
[BaseStationID] INT NOT NULL,
[RefID] INT NOT NULL,
[DisSubInsID] INT NOT NULL,
[FieldWorkerID] CHAR(7) NOT NULL,
[LastRecDate] DATETIME NOT NULL,
)
ALTER TABLE PODRAS_MS.tbl_FieldWorkers ADD CONSTRAINT PK_FieldWorkers_FWInsOnServerID PRIMARY KEY([FWInsOnServerID])
ALTER TABLE PODRAS_MS.tbl_FieldWorkers ADD CONSTRAINT FK_FieldWorkers_DisSubInsID FOREIGN KEY([DisSubInsID]) REFERENCES PODRAS_MS.tbl_DisasterSubInstances([SubInsID]) ON UPDATE CASCADE ON DELETE NO ACTION
ALTER TABLE PODRAS_MS.tbl_FieldWorkers ADD CONSTRAINT FK_FieldWorkers_BaseStationID FOREIGN KEY([BaseStationID]) REFERENCES PODRAS_MS.tbl_BaseStations([BaseStationID]) ON UPDATE CASCADE ON DELETE NO ACTION
ALTER TABLE PODRAS_MS.tbl_FieldWorkers ADD CONSTRAINT DF_FieldWorkers_LastRecDate DEFAULT(GETDATE()) FOR [LastRecDate]
GO
CREATE TABLE PODRAS_MS.tbl_FieldWorkerNodeGPSLocations
(
[FWNStatID] INT NOT NULL IDENTITY(1,1),
[FWInsOnServerID] INT NOT NULL,
[Latitude] DECIMAL(20,17) NOT NULL,
[Longitude] DECIMAL(20,17) NOT NULL,
[UpdateOn] DATETIME NOT NULL,
)
ALTER TABLE PODRAS_MS.tbl_FieldWorkerNodeGPSLocations ADD CONSTRAINT PK_FieldWorkerNodeGPSLocations_FWNStatID PRIMARY KEY([FWNStatID])
ALTER TABLE PODRAS_MS.tbl_FieldWorkerNodeGPSLocations ADD CONSTRAINT FK_FieldWorkerNodeGPSLocations_FWInsOnServerID FOREIGN KEY([FWInsOnServerID]) REFERENCES PODRAS_MS.tbl_FieldWorkers([FWInsOnServerID]) ON UPDATE CASCADE ON DELETE NO ACTION
ALTER TABLE PODRAS_MS.tbl_FieldWorkerNodeGPSLocations ADD CONSTRAINT DK_FieldWorkerNodeGPSLocations_UpdateOn DEFAULT(GETDATE()) FOR [UpdateOn]
GO
Both tables are updated through a webservice in the 1st table all the fields can be inserted through the web service but in the second table only data for [Latitude],[Longitude],[UpdateOn] fields comes through the webservice.so my problem is how can i insert the values to [FWInsOnServerID] field since its not comes through the webservice and its a reference for the 1st table???

If I understand you correctly, the insert in the second table is dependant on the result of the insert in your first table?
In this case, you could simply return the generted ID of the first table and use that result to insert into the second table.
Something like (if you're using Stored Procedures).
SELECT SCOPE_IDENTITY()
at the end of your stored procedure. And then in your .NET code which handles the database code, use that number to do the second insert.

You could do it all in a single stored procedure like this:
CREATE PROCEDURE PODRAS_MS.insert_FieldWorker()
#BaseStationID INT,
#RefID INT,
#DisSubInsID INT,
#FieldWorkerID CHAR(7),
#Latitude DECIMAL(20,17),
#Longitude DECIMAL(20,17)
AS
BEGIN
INSERT INTO
PODRAS_MS.tbl_FieldWorkers
([BaseStationID], [RefID], [DisSubInsID], [FieldWorkerID])
VALUES (#BaseStationID, #RefID, #DisSubInsID, #FieldWorkerID)
DECLARE #FWInsOnServerID INT
SELECT #FWInsOnServerID = SCOPE_IDENTITY()
INSERT INTO PODRAS_MS.tbl_FieldWorkerNodeGPSLocations
([FWInsOnServerID], [Latitude], [Longitude])
VALUES (#FWInsOnServerID, #Latitude, #Longitude)
END
You could then select the records from the same stored procedure, but it is more common to separate this out into another stored proc.
EDIT: use an output parameter
CREATE PROCEDURE PODRAS_MS.insert_FieldWorker()
#BaseStationID INT,
#RefID INT,
#DisSubInsID INT,
#FieldWorkerID CHAR(7),
#FWInsOnServerID INT output
AS
BEGIN
INSERT INTO
PODRAS_MS.tbl_FieldWorkers
([BaseStationID], [RefID], [DisSubInsID], [FieldWorkerID])
VALUES (#BaseStationID, #RefID, #DisSubInsID, #FieldWorkerID)
SELECT #FWInsOnServerID = SCOPE_IDENTITY()
END

Related

Insert the id from a previous query inside a sqlite trigger

In a sqlite3 database I would like to create a trigger on a view so that I can insert data over the view. Inside the trigger I would like to insert something in the tblmedia table. The id of the inserted row should be now also inserted into the tblbook as id.
In sqlite there are no variables. Otherwise I would store the returning value in the variable and would use it in the second query.
Can this even be achieved in sqlite?
Following my sql schema:
CREATE TABLE tblmedia(
id INTEGER PRIMARY KEY NOT NULL,
title VARCHAR NOT NULL,
raiting INTEGER,
file_name VARCHAR NOT NULL,
media_type TEXT NOT NULL
);
CREATE TABLE tblbook(
id INTEGER PRIMARY KEY NOT NULL,
author VARCHAR,
FOREIGN KEY (id) REFERENCES tblmedia(id) ON DELETE CASCADE
);
CREATE VIEW book AS
SELECT
m.id as id,
m.title as title,
b.author as author,
m.raiting as raiting,
m.file_name as file_name
FROM tblbook b
LEFT JOIN tblmedia m ON m.id = b.id;
CREATE TRIGGER insert_book
INSTEAD OF INSERT ON book
BEGIN
INSERT INTO tblmedia(title, raiting, file_name)
VALUES(new.title, new.raiting, new.file_name);
INSERT INTO tblbook(id, author)
VALUES (xx, new.author); -- xx should be the id from the previous insert
END

Auto Increment varchar datatype set as primary key

I have created a table with an Id column as varchar(20).
I need a stored procedure which can increment id by 1.
I have tried this:
ALTER PROCEDURE dbo.spInsertCatQuery
(#Users_Id varchar(20),
#Cat_Id varchar(20),
#Query varchar(100),
#Query_Title varchar(50)
)
AS
BEGIN
Declare #Query_Id bigint
SELECT #Query_Id = coalesce((select max(Query_Id) + 1 from tblCatQuery), 1);
INSERT INTO tblCatQuery
VALUES(#Query_Id, #Users_Id, #Cat_Id, #Query_Title, #Query)
END
But it is not working after 10th record.
Change the selection of Query_id from your table to below
SELECT #Query_Id=
coalesce((select max(cast(Query_Id as int)) + 1 from tblCatQuery), 1);
Based on Gordon's comment; my understanding is that since ID is varchar max(id) is not fetching the correct max value but casting it will do so.
For example try this
create table testtab (id varchar(10));
insert into testtab values(2),(200),(53)
If you say below it will return 53
select MAX(id) from testtab
but this one will return 200
select MAX(cast(id as int)) from testtab
Tested in SQL SERVER 2008 R2
You do know your stored procedure has an implicit race condition, don't you?
Between your calculating the new query id and your table insert getting committed, another session can come in, get exactly the same query id, insert it and get committed. Guess what happens when your insert tries to commit? First in wins; the second gets a duplicate key error. Don't ask me how I know this :)
If you really need a text query id, you might try using a computed field, something like this:
create table dbo.tblCatQuery
(
query_id int not null identity(1,1) primary key clustered ,
query_id_text as right('0000000000'+convert(varchar,id),10) ,
user_id varchar(20) not null ,
cat_id varchar(20) not null ,
query varchar(100) not null ,
query_title varchar(50) not null ,
)
Then your stored procedure looks like this:
create procedure dbo.spInsertCatQuery
#Users_Id varchar(20) ,
#Cat_Id varchar(20) ,
#Query varchar(100) ,
#Query_Title varchar(50) ,
#Query_ID varchar(10) output
AS
insert dbo.tblCatQuery ( user_id , cat_id , query_title , query )
VALUES ( #Users_Id , #Cat_Id , #Query_Title , #Query )
-- give the caller back the id of the row just inserted
set #Query_ID = ##SCOPE_IDENTITY
-- for redundancy, hand it back as the SP's return code, too
return #Query_ID
GO
It sounds like your application needs a string for the ID field, yet in the database you want it ID to behave as an auto-incrementing integer field.
Consider using an integer in the database, and when you retrieve the value and need to use it as as string, at that point convert the value to a string, either in your query or in your application.
This will solve your problem.
You must seriously review your design. I shall suggest something like this.
CREATE TABLE tblCatQuery(QueryId int NOT NULL PRIMARY KEY IDENTITY(1, 1),
UserId int NOT NULL REFERENCES tblUsers(UserId),
CatId int NOT NULL REFERENCES tblCat(CatId),
Query varchar(100), Query_Title varchar(50))
CREATE TABLE tblUsers(UserId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATE TABLE tblCat(CatId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATEPROCEDURE dbo.spInsertCatQuery
(
#Users_Id int,
#Cat_Id int,
#Query varchar(100),
#Query_Title varchar(50)
)
AS
BEGIN
INSERT INTO tblCatQuery(Users_Id, Cat_Id, Query_Title, Query)
VALUES( Users_Id, Cat_Id, Query_Title, Query)
END

Drop Unique Key and generate new unique key

I have created one table in oracle data base my table script is
CREATE TABLE wsc_widget_bundle (
id VARCHAR (50),
widgetBundle BLOB NULL,
devicesoftwareclass VARCHAR(30) NOT NULL,
widgetProfileId VARCHAR (50) NOT NULL,
bundleHash BLOB NULL,
widgetLocale VARCHAR (6) NOT NULL ,
status INT,
primary key(id),
unique(widgetProfileId, devicesoftwareclass,status),
foreign key(widgetProfileId) references wsc_widget_profile(id)
);
When i create ddl for that is looks like
create table "DEV1"."WSC_WIDGET_BUNDLE"(
"ID" VARCHAR2(50) not null,
"WIDGETBUNDLE" BLOB,
"DEVICESOFTWARECLASS" VARCHAR2(30) not null,
"WIDGETPROFILEID" VARCHAR2(50) not null,
"BUNDLEHASH" BLOB,
"WIDGETLOCALE" VARCHAR2(6) not null,
"STATUS" NUMBER,
constraint "SYS_C00323290" primary key ("ID")
);
alter table "DEV1"."WSC_WIDGET_BUNDLE"
add constraint "SYS_C00323292"
foreign key ("WIDGETPROFILEID")
references "MTP440_DEV1"."WSC_WIDGET_PROFILE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323290" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("ID");
create unique index "MTP440_DEV1"."SYS_C00323291" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("WIDGETPROFILEID","DEVICESOFTWARECLASS","STATUS");
create index "MTP440_DEV1"."TEST" on "MTP440_DEV1"."WSC_WIDGET_BUNDLE"("DEVICESOFTWARECLASS","STATUS","WIDGETLOCALE","WIDGETPROFILEID");
Now i want to write alter script to alter unique key constrain of my table but as at creation of table I didn't mention the name of my unique key name it is given by system like SYS_C00323291
So how can I write alter script to drop that unique key whose name is not known to me and generation new one
You can find the name of the constraint by querying the user_constraints and user_cons_columns views.
Alter table x
drop constraint pk;
Alter table x
add constraint New_constraint_name PRIMARY KEY (colname);

how do I override the autoincremented primary key when doing an insert

In MS SQL I would use
SET IDENTITY INSERT ON
How do I do something similar in SQLite. I am trying to upgrade a database and want to maintain the IDs from the original
Thanks
You don't need to set IDENTITY INSERT, because it is always possible to set the value explicitly. With SQLite, you can just insert into the ROWID column:
drop table test;
create table test(name varchar);
insert into test(name) values('Hello');
insert into test(rowid, name) values(10, 'World');
select rowid, name from test;
The same if you use an autoincrement primary key:
drop table test;
create table test(id integer primary key autoincrement, name varchar);
insert into test(name) values('Hello');
insert into test values(10, 'World');
select * from test;
See also http://www.sqlite.org/autoinc.html

Use trigger for auto-increment

I'm trying to solve the problem that composite keys in sqlite don't allow autoincrement.
I don't know if it's possible at all, but I was trying to store the last used id in a different table, and use a trigger to assign the next id when inserting a new reccord.
I have to use composite keys, because a single pk wouldn't be unique (because of database merging).
How can I set a field of the row being inserted based on a value in a different table
The query so far is:
CREATE TRIGGER pk BEFORE INSERT ON product_order
BEGIN
UPDATE auto_increment SET value = value + 1 WHERE `table_name` = "product_order";
END
This successfully updates the value. But now I need to assign that new value to the new record. (new.id).
If you use an AFTER INSERT trigger then you can update the newly inserted row, as in the following example.
CREATE TABLE auto_increment (value INT, table_name TEXT);
INSERT INTO auto_increment VALUES (0, 'product_order');
CREATE TABLE product_order (ID1 INT, ID2 INT, name TEXT);
CREATE TRIGGER pk AFTER INSERT ON product_order
BEGIN
UPDATE auto_increment
SET value = value + 1
WHERE table_name = 'product_order';
UPDATE product_order
SET ID2 = (
SELECT value
FROM auto_increment
WHERE table_name = 'product_order')
WHERE ROWID = new.ROWID;
END;
INSERT INTO product_order VALUES (1, NULL, 'a');
INSERT INTO product_order VALUES (2, NULL, 'b');
INSERT INTO product_order VALUES (3, NULL, 'c');
INSERT INTO product_order VALUES (4, NULL, 'd');
SELECT * FROM product_order;

Resources