Currently, I'm working on a project for a shop. The problem I encountered is that the "INSERT" query didn't actually insert anything.
The try-catch didn't find anything wrong, which is adding my confusion. I have also debugged the code and found nothing abnormal.
koneksi.Open();
MySqlCommand masuk = new MySqlCommand(a, koneksi);
masuk.CommandType = CommandType.StoredProcedure;
Random utk_id = new Random();
int panggil_acak = utk_id.Next();
masuk.Parameters.AddWithValue("_id_transaksi", Convert.ToString(panggil_acak));
masuk.Parameters.AddWithValue("_id_barang", Convert.ToString(id.Text));
masuk.Parameters.AddWithValue("_nama_barang", Convert.ToString(nama.Text));
masuk.Parameters.AddWithValue("_harga_satuan", Convert.ToString(harga.Text));
masuk.Parameters.AddWithValue("_jumlah_barang", Convert.ToString(jmlh_brg_beli.Text));
masuk.Parameters.AddWithValue("_diskon", Convert.ToString(diskon_rp.Text));
masuk.Parameters.AddWithValue("_harga_total", Convert.ToString(harga_barang_total.Text));
masuk.Parameters.AddWithValue("_tgl_transaksi", Convert.ToString(DateTime.Now.ToString()));
//execute command
masuk.ExecuteNonQuery();
clear text area and refresh data grid
rstArea();
isiDgrid();
the command is a stored procedure and the application gives no error feedback.
CREATE DEFINER=`root`#`localhost` PROCEDURE `belanjaTemp_add`(
_id_transaksi varchar(20),
_id_barang varchar(10),
_nama_barang varchar(255),
_harga_satuan varchar(10),
_jumlah_barang varchar(10),
_diskon varchar(45),
_harga_total varchar(10),
_tgl_transaksi varchar(45)
)
BEGIN
if(_id_transaksi = 0)
then
insert into komodo.penjualan_temp
(id_transaksi, id_barang, nama_barang, harga_satuan, jumlah_barang, diskon, harga_total, tgl_transaksi)
values
(_id_transaksi, _id_barang, _nama_barang, _harga_satuan, _jumlah_barang, _diskon, _harga_total, _tgl_transaksi);
END if;
END
I expected the database will be updated but it's not updated.
The screenshot for succeed confirmation :
https://ibb.co/b26YdBY
My question : how do I manage to get the data inserted?
Try using ExecuteStoredProcedure() instead of ExecuteNonQuery();
Related
I'm new to Dapper - please help me. How can I get the inserted record value after a successful insert?
Stored procedure:
ALTER PROCEDURE Sp_InsertTestData
#Name varchar(50),
#gender int,
#refres int OUTPUT
AS
BEGIN
INSERT INTO Test_Master (Name, Gender)
VALUES (#Name, #gender);
SELECT #refres = SCOPE_IDENTITY()
SELECT #refres as M_SID
END
When I execute this stored procedure in SQL like this:
DECLARE #refres INT
EXEC Sp_InsertTestData 'test12',1,#refres
I'm getting an output showing the last inserted row's value.
But when this stored procedure is executed from C# code, every time I'm getting a value of 1:
using (SqlConnection con = new SqlConnection(_configuration.GetConnectionString("DatabaseConnection")))
{
con.Open();
SqlTransaction sqltrans = con.BeginTransaction();
var param = new DynamicParameters();
param.Add("#Name", Bindtestmaster.Name);
param.Add("#gender", Bindtestmaster.Gender);
param.Add("#refres");
res = con.Execute("Sp_InsertTestData", param, sqltrans, 0, CommandType.StoredProcedure);
}
That's because you are getting the result of the stored procedure call, which tells you the number of rows inserted (which is 1).
You want to read the output parameter #refres (and add it to your DynamicParameters as an output parameter)
/* ... */
param.Add("#refres", dbType: DbType.Int32, direction: ParameterDirection.Output);
con.Execute("Sp_InsertTestData", param, sqltrans,0,CommandType.StoredProcedure);
var yourId = param.Get<int>("#refres");
Btw, on your stored procedure instead of:
select #refres=SCOPE_IDENTITY()
You might want to prefer this:
SET #refres = SCOPE_IDENTITY() AS INT
And I'm not sure what that last SELECT is there for
Or directly output the inserted ID (using the OUTPUT SQL clause on the INSERT) and then you could read the result, and not have an output parameter at all.
Since your stored procedure also selects the output:
select #refres as M_SID
An easier way of doing this might be:
var id = con.ExecuteScalar<int>("Sp_InsertTestData", new {
Name = Bindtestmaster.Name,
gender = Bindtestmaster.Gender
}, sqltrans, 0, CommandType.StoredProcedure);
and forget DynamicParameters etc. You could also consider using the OUTPUT clause in the SQL, to simplify it:
ALTER PROCEDURE Sp_InsertTestData
#Name varchar(50), #gender int
AS
BEGIN
INSERT INTO Test_Master(Name, Gender)
OUTPUT INSERTED.Id -- whatever the column is here
VALUES (#Name, #gender);
END
I'm running a stored procedure inside a foreach loop in c#. After completion, all the rows of a column are getting updated with the top most value. Below is the stored procedure:
ALTER PROCEDURE [dbo].[getservername8]
#number varchar(255)
AS
DECLARE #server_name varchar(500)
SELECT #server_name = short_description
FROM [Event_alerts].[dbo].[event_alerts]
DECLARE #s AS varchar(50)
SELECT #s = SUBSTRING(#server_name, CHARINDEX('-', #server_name) + 15, 50)
UPDATE event_alerts
SET server_name = #s
WHERE number = #number
This is the C# code:
using (SqlCommand command2 = new SqlCommand("getservername8", conn))
{
command2.CommandType = CommandType.StoredProcedure;
command2.Parameters.AddWithValue("#number",number);
command2.Parameters["#number"].Direction = ParameterDirection.Input;
command2.ExecuteNonQuery();
}
Any help would be much appreciated
The culprit is because you are getting the same value of #server_name for each call. So #s si also same for all. that is why you are inserting the same value in the column
select #server_name = short_description from [Event_alerts].[dbo].[event_alerts]
declare #s as varchar(50)
select #s= SUBSTRING(#server_name, CHARINDEX('-', #server_name) + 15, 50)
Your code has a valid where clause, so it should only be updating the matching rows. I can only speculate that all rows have the same value for number.
However, you seem to have an error in the definition of #server_name -- and that might be the problem you are referring to. There is no where clause so it is set to an arbitrary value -- possibly from what you would call "the last row". Although that nomenclature is a misinterpretation of what happens.
Your SP is too complex anyway. I suspect that you intend:
alter procedure [dbo].[getservername8] (
#number varchar(255)
) as
begin
update ea
set server_name = substring(short_description, charindex('-', short_description) + 15, 50)
from event_alerts ea
where number = #number;
end; -- getservername8
Also note the good programming practices:
The statements end in a semicolon.
The body of the SP uses begin/end.
The end is tagged with the name of the SP.
For some reason my stored procedure is executed without any error from the code-behind in C# but it is not deleting anything at all that the stored procedure has written. I have all the correct parameters and everything. I ran the query from SQL Server with all the same parameters from the C# code and it works perfectly. I don't get why it works when I run from SQL Server but it doesn't work when I run it from my C# code in Visual Studio.
Here is my C# code that is passing the data through to the stored procedure.
string reportType = "PostClaim";
string GRNBRs = "925','926','927";
string PUNBRs = "100','100','100";
string beginningDates = "20120401";
string endDates= "20120430";
try
{
conn = new SqlConnection(ConnectionInfo);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter("RemoveReport", conn);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#ReportType", reportType);
da.SelectCommand.Parameters.AddWithValue("#GRNBR", GRNBRs);
da.SelectCommand.Parameters.AddWithValue("#PUNBR", PUNBRs);
da.SelectCommand.Parameters.AddWithValue("#DATE1", beginningDates);
da.SelectCommand.Parameters.AddWithValue("#DATE2", endDates);
da.SelectCommand.CommandTimeout = 360;
}
catch (SqlException ex)
{
//something went wrong
throw ex;
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
Here is my stored procedure. It's executing with dynamic SQL text.
ALTER PROCEDURE [dbo].[RemoveReport] (
#ReportType NVARCHAR(20),
#GRNBR VARCHAR(4000),
#PUNBR VARCHAR(4000),
#DATE1 DATETIME,
#DATE2 DATETIME
)
AS
DECLARE #SQLTEXT VARCHAR(4000)
BEGIN
SET #SQLTEXT = 'DELETE FROM TestingTable
WHERE Report='''+#ReportType+''' AND
PUNBR IN ('''+#PUNBR+''') AND
[Group] IN ('''+#GRNBR+''') AND
StartedAt BETWEEN '''+CONVERT(VARCHAR(10),#DATE1,121)+'''
AND '''+CONVERT(VARCHAR(10),#DATE2,121)+''''
PRINT #SQLTEXT <---I'll print this out to show you what exactly it is executing.
EXECUTE (#SQLTEXT)
END
Here is what the PRINT #SQLTEXT is running:
DELETE FROM MonthlyReportSchedule
WHERE Report='PostClaim' AND
PUNBR IN ('100','100','100') AND
[Group] IN ('925','926','927') AND
StartedAt BETWEEN '2012-04-01' AND '2012-04-30'
When I actually go into SQL Server to run this query, it works perfectly. But why does it not work on when executed from the C# code. Any help?
Avoid concatenating parameters to your sql, use parameterised query,
Try this...
Just noticed that you have some comma delimited lists in params.....
ALTER PROCEDURE [dbo].[RemoveReport]
#ReportType NVARCHAR(20),
#GRNBR VARCHAR(4000),
#PUNBR VARCHAR(4000),
#DATE1 DATETIME,
#DATE2 DATETIME
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQLTEXT NVARCHAR(MAX);
Declare #GRNBR_xml xml,#PUNBR_xml xml;
SET #GRNBR_xml = N'<root><r>' + replace(#GRNBR, ',','</r><r>') + '</r></root>';
SET #PUNBR_xml = N'<root><r>' + replace(#PUNBR, ',','</r><r>') + '</r></root>';
SET #SQLTEXT = N'DELETE FROM TestingTable
WHERE Report = #ReportType
AND PUNBR IN (select r.value(''.'',''varchar(max)'') as item
from #PUNBR_xml.nodes(''//root/r'') as records(r))
AND [Group] IN (select r.value(''.'',''varchar(max)'') as item
from #GRNBR_xml.nodes(''//root/r'') as records(r))
AND StartedAt BETWEEN #DATE1 AND #DATE2'
EXECUTE sp_executesql #SQLTEXT
,N'#ReportType NVARCHAR(20) , #GRNBR_xml xml,
#PUNBR_xml xml,#DATE1 DATETIME,#DATE2 DATETIME'
,#ReportType
,#GRNBR_xml
,#PUNBR_xml
,#DATE1
,#DATE2
END
Note
Make sure you pass the comma delimited list as 925,926,927 and not as '925','926','927'
Try adding this line in order to be executed
da.SelectCommand.ExecuteNonQuery();
This will execute a call to your stored procedure.
good luck
I have a SQL stored procedure for updating my table. But when executing the query via C#, xslt the one of the columns deleted from the table.
My stored procedure is
ALTER PROCEDURE [dbo].[kt_editingnotes]
(#NOTE NVARCHAR (512),
#ITEMNUMBER NVARCHAR (512),
#ACCOUNT NVARCHAR (512),
#CODE NVARCHAR(512)
)
AS
UPDATE NOTES
SET TXT = #NOTE
WHERE NOTESRECID = (SELECT ISP_EFAVORITLINE.ROWNUMBER
FROM ISP_EFAVORITLINE
WHERE ISP_EFAVORITLINE.ACCOUNT = #ACCOUNT
AND ISP_EFAVORITLINE.ITEMNUMBER = #ITEMNUMBER
AND ISP_EFAVORITLINE.CODE = #CODE)
return
and I am calling it like this:
ExecStoredProcedure('kt_editingnotes', concat('#ITEMNUMBER:', $ITEMNUMBER,', #ACCOUNT:', $ACCOUNT,', #CODE:', $CODE))
What is the problem? Can anyone help?
editingI noticed in the ExecStoredProcedure that you execute the procedure 'kt_deletenotes' instead of 'kt_editingnotes'. Try changing the line where you call your procedure to call the correct procedure.
ExecStoredProcedure('kt_editingnotes', concat('#ITEMNUMBER:', $ITEMNUMBER,', #ACCOUNT:', $ACCOUNT,', #CODE:', $CODE))
Ok so I am new here :) I am relatively new to SQL, and I am trying to insert data into multiple tables. I have both inserts to work however I want it so if one fails neither are committed.
The tables look like this:
Student -
StudentID - int PK,
StudentName - Varchar,
etc ...
Class -
ClassID - int PK,
ClassName - varchar,
etc...
StudentClass -
StudentID,
ClassID,
What I am trying to do is create a new Student whom can belong to multiple classes. So I have created the Student class table to break up the many-many relationship. I have a stored procedure to insert a new student and return the newest StudentID and then I use this StudentID, in a new stored procedure, and a table value parameter to insert multiple rows into StudentClass table. These are the stored procedures:
Create A Student:
#FirstName varchar(20) = '',
#LastName varchar(20) = '',
#PredictedGrade char(1) = '',
#ActionPlan bit = 0,
#StudentActive bit = 1,
#StudentID int out
INSERT INTO Student (FirstName, LastName, PredictedGrade, ActionPlan, StudentActive)
VALUES (#FirstName, #LastName, #PredictedGrade, #ActionPlan, #StudentActive)
SET #StudentID = SCOPE_IDENTITY()
Add Multiple Rows To StudentClass Table:
(#StudentClassCollection As InsertStudentClass READONLY)
INSERT INTO StudentClass(StudentID, ClassID)
SELECT StudentID, ClassID FROM #StudentClassCollection
So both of these work however I don't know how to make it so if one fails the other will not execute and changes will not be committed? So effectively I need to perform both actions one after the other in the same stored procedure? I think! As I said I am new so if I have done anything wrong please let me know I will correct it :)
In case of an error, rollback will be issued automatically
SET XACT_ABORT ON
begin transaction
-- YOUR WORK HERE
commit transaction
try like the below
using (SqlConnection connection= new SqlConnection(connectionstring))
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
try
{
SqlCommand command = new SqlCommand("proc1",connection);
//execute the above command
command.CommandText="proc2";
//execute command again for proc2
transaction.Commit();
}
catch
{
//Roll back the transaction.
transaction.Rollback();
}
}
begin tran
// all insert , update script here
IF ##ERROR <> 0
BEGIN
ROLLBACK tran
END
ELSE
commit tran