Insert into view returns 2 rows affected - c#

In Sql Server 2005, I have two databases. In the first one I have a table like this:
CREATE TABLE [dbo].[SG](
[id] [int] IDENTITY(1,1) NOT NULL,
[sgName] [nvarchar](50) NOT NULL,
[active] [bit] NOT NULL,
[hiddenf] [int] NOT NULL
)
In the second, I have a view like this:
CREATE VIEW [dbo].[SG] AS
SELECT id,sgName, active
FROM [FirstDatabase].dbo.SG WHERE hiddenf = 1
with a trigger like this:
CREATE TRIGGER [dbo].[InsteadTriggerSG] on [dbo].[SG]
INSTEAD OF INSERT AS BEGIN
INSERT INTO [FirstDatabase].dbo.SG(sgName,active,hiddenf)
SELECT sgName,COALESCE (active,0), 1 FROM inserted
END
When I insert into the view:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand("INSERT INTO SG(sgName, active) VALUES('Test', 1)", connection);
var affectedRows = command.ExecuteNonQuery();
Assert.AreEqual(1, affectedRows);
}
I get affectedRows equal to two, while my expected value is 1.

This sort of question usually makes me think "triggers".
I have just created an exact copy of your scenario (thanks for the detailed instructions) and I am kind of seeing similar results.
By kind of, I meant that when I execute the insert, SSMS outputs
(1 row(s) affected)
(1 row(s) affected)
but when I checked the original database, only one row had been added.
To solve your problem, do this:
ALTER TRIGGER [dbo].[InsteadTriggerSG] on [dbo].[SG]
INSTEAD OF INSERT AS BEGIN
SET NOCOUNT ON -- adding this in stops it from reporting from in here
INSERT INTO [TEST].dbo.SG(sgName,active,hiddenf)
SELECT sgName,COALESCE (active,0), 1 FROM inserted
END
The issue is that both the trigger and the actual table on the original database are reporting that they've updated a row. If you remove this reporting from the trigger, but leave it in the original database, you will always get a true answer, whether you update via the view or straight into the original table directly.

Related

How to insert data from 2 different sources into 2 different tables in SQL server using Web application?

Ok, basically i have created Web application in Visual Studio 2012 Ultimate and one page has this design:
I have also created 3 tables in database :
products:
[id]
[name]
auctions:
[id]
[productid]
[lastbider]
[bidvalue]
[lastbid]
users:
[id]
[name]
[password]
[bids]
The thing i need is when i click on button it needs to insert text from Textbox into [name] from products table and also insert number from Listbox into [bidvalue] from auctions table. How do i do this, do i need 2 SqlCommands?
Yes, basically you are trying to perform INSERT into two different tables and so you need to perform two different INSERT operations. Though, I suspect you probably want to perform an UPDATE instead but can't say for sure unless you clarify it.
Again, you can perform both the operation in single shot using a stored procedure like
create procedure usp_addData(#name varchar(10), #bidvalue INT)
as
begin
//Perform first insert/update in products table using the #name parameter
//perform second insert/update in auctions table using the #bidvalue parameter
end
Call this stored procedure from your application instead of making two different DB calls.
*** Omitted C# code samples to keep the answer simple. You can get many example of calling stored procedure from C# in SO.
Try this and just call
InsertData("Insert into Products (Name) Values ('" + txtName.Text + "'); Insert Into Auctions (bidvalue) Values ('" + lstBidValues.SelectedValue + "');");
public void InsertData(string query)
{
using (SqlConnection con = new SqlConnection("Your connection string here"))
{
if (con.State != ConnectionState.Open)
con.Open();
using (SqlCommand command = con.CreateCommand())
{
command.CommandText = query;
command.ExecuteNonQuery();
}
}
}
Since you will need the ProductId in your Auctions table, you will need to do an insert in Products and then get the productId you created in your sql to add it to your Auctions table together with the bidValue that you have. This can be done with one SqlCommand that calls your stored procedure which should look like below...
BEGIN TRANSACTION
INSERT INTO PRODUCTS VALUES('PRODUCT NAME')
DECLARE #newProductId int = SELECT SCOPE_IDENTITY()
INSERT INTO AUCTIONS(ProductId, lastBidder, bidValue, lastbid)
VALUES (#newProductId, 'yourlastbidder, 'bidValue', 'lastbid')
END TRANSACTION

How to merger/combine data from two sql databases that have a same structure?

I am writting an program in C#, that use SQL Server database.
My program include a blank database (sample database) that allow users can create a new database.
For example:
User 1 use my program to create a new database (DB1) on his computer, then he import/enter some data into DB1
User 2 use my program to create a new database (DB2) on his computer, then he import/enter some data into DB2
Now, I have both two database (DB1, DB2). Do you know how to merge/combine two databases to have unique database that contain all users' data ?
Can you help me ?
please see my demo screenshot
If the use of the procedures applicable to your application you might use the MERGE statement to combine your data.
To learn more about merging follow http://msdn.microsoft.com/en-us/library/bb510625.aspx topic
Added OUTPUT usage sample, it shows how to get inserted row's PK to insert in other related table.
CREATE TABLE #teachers(
[ID] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](15) NOT NULL
)
CREATE TABLE #pupils(
[ID] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](15) NOT NULL
)
CREATE TABLE #createdTeachers ([ID] [int])
CREATE TABLE #createdPupils ([ID] [int])
insert into #teachers output inserted.ID into #createdTeachers values ('teacher#2')
insert into #teachers output inserted.ID into #createdTeachers values ('teacher#1')
insert into #pupils output inserted.ID into #createdPupils values ('pupil#2')
insert into #pupils output inserted.ID into #createdPupils values ('pupil#1')
select t.ID as NEW_TEACHER_ID,p.ID as NEW_PUPIL_ID from #createdTeachers as t , #createdPupils as p
I did not prepare sample, which describes your diagram fully but necessary concepts are shown.
You might use "select t.ID as NEW_TEACHER_ID,p.ID as NEW_PUPIL_ID from #createdTeachers as t , #createdPupils as p" to insert teacherId, pupilId etc into Teacher_Pupil table
Merging to database is mentioned here Please refer : http://msdn.microsoft.com/en-us/library/ms140052.aspx

INSERT in one table but it locks another table [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm now having a problem with SQL Server table lock. I'm developing in C#.
My queries run under 1 transactions.
I name it for the easiest way to recognize.
"setTransaction"
setTransaction is only for "INSERT / UPDATE / DELETE".
if I want to do SELECT. I'll use SqlDataAdapter.
If I want to do INSERT / UPDATE or DELETE, it's the time to use setTransaction.
here is the table structure of each ...
[LOG](
[log_id] [int] IDENTITY(1,1) NOT NULL,
[subject] [text] NOT NULL,
[query] [text] NOT NULL,
[log_datetime] [datetime] NOT NULL,
[user_id] [int] NOT NULL,
[emp_id] [int] NULL,
[old_value] [text] NULL
)
[RESERVATION_DETAIL](
[**reservation_detail_id**] [int] IDENTITY(1,1) NOT NULL,
[reservation_id] [int] NOT NULL,
[spa_program_id] [int] NULL,
[price] [int] NULL,
[oil] [int] NULL
)
[RESERVATION_THERAPIST](
[reservation_therapist_id] [int] IDENTITY(1,1) NOT NULL,
[**reservation_detail_id**] [int] NOT NULL,
[therapist_id] [int] NOT NULL,
[hours] [int] NULL,
[mins] [int] NULL
)
[LOG] is working independently.
[RESERVATION_DETAIL] are connected to [RESERVATION_THERAPIST] via reservation_detail_id
The problem is ....
BEGIN TRANSACTION.
I want to delete a record from "RESERVATION_DETAIL" with reservation_detail_id = 25
I select a record from "RESERVATION_DETAIL" with reservation_detail_id = 25
SELECT * FROM RESERVATION_DETAIL WHERE RESERVATION_DETAIL_ID = 25
I insert into table "LOG" with data from 2.
INSERT INTO LOG ( subject, query, log_datetime, user_id, emp_id, old_value ) VALUES (
'DELETE TEMP RESERVE FROM RES_DETAIL[RES_DETAIL_ID:25]',
'DELETE FROM RESERVATION_DETAIL WHERE RESERVATION_DETAIL_ID = 25',
CURRENT_TIMESTAMP,
1,
NULL, 'reservation_detail_id:25|reservation_id:25|spa_program_id:-1|price:|oil:'
)
now I delete from "RESERVATION_DETAIL" where reservation_detail_id = 25
Then I want to delete a record from "RESERVATION_THERAPIST" with reservation_detail_id = 25
DELETE FROM RESERVATION_DETAIL WHERE RESERVATION_DETAIL_ID = 25
I select a record from "RESERVATION_THERAPIST" with reservation_detail_id = 25 <----- I GOT THE LOCK HERE !!
SELECT * FROM RESERVATION_THERAPIST WHERE RESERVATION_DETAIL_ID = 25
I insert into table "LOG" with data from 5.
Finally I will delete from "RESERVATION_THERAPIST" where reservation_detaiil_id = 25
Above steps were run consequently.
the step 5 (which is about table "RESERVATION_THERAPIST") is now wait on step 3 (about table "LOG") to finished but It never finished.
I don't understand why I insert into table LOG but it put the lock onto the table B !? or this is not a lock !?
there were the queries before the above step that insert into LOG without any problem.
Now I can solve my problem.
The queries and steps are already OK.
But I forgot that the table "RESERVATION_DETAIL" has a trigger that will run right after the DELETE query is committed.
So the trigger will go to delete a record in "RESERVATION_THERAPIST" automatically and this step is under the transaction.
So "RESERVATION_THERAPIST" was locked up after "DELETE FROM RESERVATION_DETAIL" but before I can "SELECT * FROM RESERVATION_THERAPIST"
Several things could cause the table to be locked until the deletion is through:
You are directly deleting from the table you are trying to select from
You have cascade delete turned on for a parent table to the one that is locked.
You have a trigger on another table that you are taking an action from that also deletes from the table.
You are trying to delete the tables out of order (child table are always deleted first, then parent ones. When deleting from a parent table, it will check to see if child records exist. This of course takes longer than a straight delete and will cause a rollback if the child data exists which takes longer yet.
You have deadlock between two process running at the same time.
You got the lock on B because you deleted from it.

Double records in result set

I have found a strange phenomena on MSSQL server.
Let say we have a table:
CREATE TABLE [testTable]
(
[ID] [numeric](11, 0) NOT NULL,
[Updated] [datetime] NULL,
PRIMARY KEY (ID)
);
I do a simple select based on Updated field:
SELECT TOP 10000 ID, Updated
FROM testTable
WHERE Updated>='2013-05-22 08:55:12.152'
ORDER BY Updated
And now comes the fun part: how can I have in result set double records - I mean same ID in 2 records with different Updated value.
For me it seems to be, that the Updated datetime value was changed and it was included one more time in result set. But is it possible?
UPDATE:
Source code I using for downloading data from SQL server:
using (SqlCommand cmd = new SqlCommand(sql, Connection) { CommandTimeout = commandTimeout })
{
using (System.Data.SqlClient.SqlDataAdapter adapter = new System.Data.SqlClient.SqlDataAdapter(cmd))
{
DataTable retVal = new DataTable();
adapter.Fill(retVal);
return retVal;
}
}
Connection = SqlConnection
sql = "SELECT TOP 10000 ...."
Your question seems to lack some details but here's my ideas.
The first case I'd think of would be that you are somehow selecting those IDs twice (could be a join, group by, ...). Please manually check inside your table (in MSSQL Server rather than inside a function or method) to see if there is dupplicated IDs. If there is, the issue is that your Primary Key hasn't been set correctly. Otherwise, you will need to provide all the relevant code that is used to select the data in order to get more help.
Another case might be that someone or something altered the primary key so it is on both ID and Updated, allowing the same ID to be inserted twice as long as the Updated field doesn't match too.
You may also try this query to see if it gets dupplicated IDs inside your context:
SELECT ID
from testTable
ORDER BY ID
I hope this helps.

Stored Procedure with IsIDenity and cmd.Parameters.Add

I am creating an ASP.NET Wiki for myself to track the knowlege I gain in C# and other language.
I have created a Stored Procedure to insert a category into a DB, the DB has two fields C_ID(int) and Category(varchar 25). In my ASP page, there is no field for C_ID, it increments automatically by IsIdentiy = true;
When I try to excute it, it fails. What is the best approach to handle this?
Code:
ALTER PROCEDURE dbo.InsertCategory
#ID int,
#CATEGORY varchar(25)
AS
INSERT INTO Wiki
(C_ID, C_Category)
Values (#ID, #CATEGORY)
/* SET NOCOUNT ON */
RETURN
Did I miss something to insert from the .aspx page?
try
{
//create a command object identifying the Stored Procedure
SqlCommand cmd = new SqlCommand("InsertCategory", conn);
//Set the command type
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("Category", txtAddCatagory));
cmd.ExecuteNonQuery();
}
Just omit the id from the insert. If you configured identity correctly, the database will take care of increasing the number. For example:
GO
ALTER PROCEDURE dbo.InsertCategory(#CATEGORY varchar(25))
AS
INSERT INTO Wiki (C_Category) Values (#CATEGORY)
GO
To verify the identity is set correctly, if you script the table, the C_id column should look like;
[C_id] [int] IDENTITY(1,1) NOT NULL,
Or even better:
[C_id] [int] IDENTITY(1,1) PRIMARY KEY,
So you're getting an exception that you cannot insert into an identity column, right? The trick is to not specify the identity column in your insert statement, because it automatically get populated... ;)
ALTER PROCEDURE dbo.InsertCategory #CATEGORY varchar(25) AS
INSERT INTO Wiki (C_Category) Values (#CATEGORY) /* SET NOCOUNT ON */ RETURN

Categories