Use Stored procedures that uses the "EXECUTE" command in a TableAdapter - c#

I am writing a program that needs to call a MSSQL stored procedure called dbo.getsystemnumber; this procedure generates the next pyd_number which I need to insert a new line in the paydetail table. This is what the procedure looks like:
ALTER PROCEDURE [dbo].[getsystemnumber](#p_controlid varchar(8), #p_alternateid varchar(8))
AS
DECLARE #return_number int
EXECUTE #return_number = dbo.getsystemnumber_gateway #p_controlid, #p_alternateid, 1
RETURN #return_number
I'm using the c# tableadapter to call this procedure but when I do call it and say put it on a label or listbox, it just returns a value of 0. The function still updates in SQL server to the next number when I run the program.
TMW_Test2DataSetTableAdapters.paydetailTableAdapter returnPydNumber = new TMW_Test2DataSetTableAdapters.paydetailTableAdapter();
lbPydnumber.Items.Add(Convert.ToInt32(returnPydNumber.getsystemnumber("PYDNUM", " ")));
However, when I use the preview data option in the tableadapter view I get the right number that I'm supposed to get. In SQL Server we call it like this:
declare #pyd_number int
execute #pyd_number = dbo.getsystemnumber N'PYDNUM', NULL
select #pyd_number

TableAdapters use the result of a SELECT statement for their data, not the RETURN value of a query. Under the hood, a single value TableAdapter will use ExecuteScalar(), which takes the first column in the first row of the resultset.
This blog post explains this and a workaround. Either change the store procedure to SELECT the value instead of RETURNing it, or change the generated code to look at the ReturnValue of the database call.

Related

Running SQL Query from a SQL Query

I have a table where I want to run a query that I get from a query.
What I want to do is return the name (checkbooks, clients, etc) and the results of the sql queries per each type. all within one query result so I can send that data out. I have no clue where to start.
You could try using your first query to open a cursor, then within the loop execute the result string as dynamic SQL. I dont know what your tables or columns are called, but assuming table is called Table and column containing those Selects is Result, you could try something like:
declare commands cursor for
select result from table
declare #cmd varchar(max)
open commands
fetch next from commands into #cmd
while ##FETCH_STATUS=0
begin
exec(#cmd)
fetch next from commands into #cmd
end
close commands
deallocate commands
Inspired by this question:
execute result of select statement
This doesn't look like a good idea, unless there is no way for you to change this approach.
If you are using EF, after getting the row, you can execute the query in the query test field like this
context.MyEntity.SqlQuery("SELECT * FROM dbo.MyEntity").ToList();
https://learn.microsoft.com/en-us/ef/ef6/querying/raw-sql
You can do the same with different ORM, the idea is simple get the string in the field and pass it to the execute query.
FYI: Is saving SQL statements in a table for executing later a bad idea?
https://softwareengineering.stackexchange.com/questions/227922/is-saving-sql-statements-in-a-table-for-executing-later-a-bad-idea

AS400 Call a stored procedure from another stored procedure

I am trying to call a stored procedure from another stored procedure.
I tried different syntax but with no success.
The first stored procedure returns a table. For the test, I just want to return from the second stored procedure what I got from the first one.
First stored procedure (SP01):
BEGIN
DECLARE C2 CURSOR WITH RETURN FOR
SELECT DISTINCT TBL.*
FROM LIB.TABLE1 TBL;
OPEN C2 ;
END
It works fine when calling it from c#.
Second stored procedure (SP02):
BEGIN
DECLARE C2 CURSOR WITH RETURN FOR
CALL SP01();
OPEN C2 ;
END
I am getting an error:
Vendor Code: -104
Message: [SQL0104] Token SP01 was not valid. Valid tokens: ;. Cause ....
A syntax error was detected at token SP01.
What is the correct syntax / approach for SP02?
EDITED:
In ms access, I was able to create a query QUERY2 based on another query QUERY1:
SELECT * FROM QUERY1;
or even joining it like a table
SELECT * FROM TABLE1 INNER JOIN QUERY1 ON (TABLE1.FIELD1 = QUERY1.FIELD1);
I need to move all my tables and queries from mdb to AS400 and write a C# application that use those queries.
I do not see so much examples on the net, maybe my approach is wrong.
I have multiple queries to run and each one depends on another one. I thought calling one stored procedure from my C# application and this one will call to another one and so on.
Is it a correct way to run a series of queries that depends one to each other?
Or is there a way to call from my c# application to all the queries independently and from the code to build the dependency between them, look like this approach is wrong?
If you are using IBM i version 6.1 or earlier, you cannot access result sets returned by a stored procedure using a language SQL stored procedure. For version 7.1 or later, you can use the ASSOCIATE RESULT SET LOCATORS statement to retrieve the result sets. See the ASSOCIATE LOCATORS statement in the SQL Reference manual (http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzassocloc.htm?lang=en) for more information.
Once you have the locator, you use the ALLOCATE CURSOR statement (http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_72/db2/rbafzalloccsr.htm?lang=en) to get a cursor from the RESULT SET LOCATOR.
Further examples can be found here: http://www.itjungle.com/fhg/fhg082510-printer02.html

pass input parameters to stored procedure from sql table

i want to pass input parameters like start date and end date in the table T1 and pass to stored procedure SP1 from T1.is it possible,and also i want to execute this sp in c# script task in ssis.Thanks
Check this out for both : with '?'s and with C#
https://www.simple-talk.com/sql/ssis/passing-variables-to-and-from-an-ssis-task/
Hi i have sort out the problem initially i took the execute sql task and select the values from the table and store those value in the result set an after that i have taken dataflow task and oled source connection and execute the sp in that and pass the earlier result set values to the stored procedure and execute it and store the rsult in the one sql table.

Cannot alter table with LINQ TO SQL and stored procedure

I have to alter the table Statistic when I add a new metric in the table Metric I add a column in table Statistic.
I used a stored procedure that allows me to alter the table Statistic so the code :
CREATE PROCEDURE dbo.addnewmetricInstat
(
#MetricName varchar(254),
#TypeMetric varchar(254)
)
AS
IF (#TypeMetric='int')
Begin
alter table Statistic
add #MetricName int null
end
ELSE if (#TypeMetric='string')
begin
alter table Statistic
add #MetricName varchar(254) null
end
Then I successfully called the stored procedure but the columns is not added. The code I used in C# for calling this stored procedure is:
using (DataClassesDataContext db = new DataClassesDataContext("Data Source=EMEA-TUN-WS0367\\SQLEXPRESS;Initial Catalog=Perfgas;Integrated Security=True"))
{
db.addnewmetricInstat(metric.MetricName, metric.Type);
db.SubmitChanges();
}
First you shoud not be trying to call the sp from your application until you have tested it in SSMS. That way you know if the problem is your call or the sp. It will save you much debugging time if you do this.
Your proc is the problem. You will need to use dynamic SQl for this. Right now you are trying to add a column called MetericName because you didn't use the variable. This would work once, but of course the second time you run it, you will get an error becasue teh column already exists. However you can;t just throw a variable into an alter table statement, you must use dynamic SQL.

ChangeConflictException when updating rows with LINQ-to-SQL

I have a form which contains a data grid and a save button.
When the user clicks the save button I check for new rows by checking a specific column. If its value is 0 I insert the row to database, and if the column value is not 0 then I update that row.
I can insert correctly but when updating an exception occurs:
ChangeConflictException was unhandled,1 of 6 updates failed.
I have checked the update statement and I'm sure it's correct. What is the problem, can any one help me?
int id;
for (int i = 0; i < dgvInstructores.Rows.Count - 1; i++)
{
id = int.Parse(dgvInstructores.Rows[i].Cells["ID"].Value.toString());
if (id == 0)
{
dataClass.procInsertInstructores(name, nationalNum, tel1, tel2,
address, email);
dataClass.SubmitChanges();
}
else
{
dataClass.procUpdateInstructores(id, name, nationalNum, tel1, tel2,
address, email);
dataClass.SubmitChanges();
}
}
I'm using linq to query sql server2005 database and vs2008
the stored procedure for 'procUpdateInstructores' is :
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER proc [dbo].[procUpdateInstructores]
#ID int,
#name varchar(255),
#NationalNum varchar(25),
#tel1 varchar(15),
#tel2 varchar(15),
#address varchar(255),
#email varchar(255)
as
begin
BEGIN TRANSACTION
update dbo.Instructores
set
Name = #name , NationalNum = #NationalNum ,
tel1 = #tel1 , tel2 = #tel2 , address = #address , email = #email
where ID = #ID
IF (##ROWCOUNT > 0) AND (##ERROR = 0)
BEGIN
COMMIT TRANSACTION
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
end
In my experience, (working with .net forms and mvc with linq-to-sql) I have found that several times if the form collection contains the ID parameter of the data object then the update surely fails.
Even if the ID is the actual ID, it is still flagged as 'propertyChanged' when you bind it or update it or assign to another variable.
As such can we see the code for your stored procs? More specifically, the update proc?
The code you have posted above is fine, the exception should be coming from your stored proc.
However if you are confident that the proc is correct then perhaps look at the HTML code being used to generate the table. Some bugs might be present with respect to 0/1 on ID columns, etc.
In the absence of further information (what your SQL or C# update code looks like...) my first recommendation would be to do SubmitChanges once, outside the for loop, rather than submitting changes once per row.
It appears in this case that you are using a DataGridView (thus WinForms). I further guess that your dataClass is persisted on the form so that you loaded and bound the DataGridView from the same dataClass that you are trying to save the changes to in this example.
Assuming you are databinding the DataGridView to entities returned via LINQ to SQL, when you edit the values, you are marking the entity in question that it is needing to be updated when the next SubmitChanges is called.
In your update, you are calling dataClass.procUpdateInstructores(id, name, nationalNum, tel1, tel2, address, email); which immediately issues the stored procedure against the database, setting the new values as they have been edited. The next line is the kicker. Since your data context still thinks the object is still dirty, SubmitChanges tries to send another update statement to your database with the original values that it fetched as part of the Where clause (to check for concurrency). Since the stored proc updated those values, the Where clause can't find a matching value and thus returns a concurrency exception.
Your best bet in this case is to modify the LINQ to SQL model to use your stored procedures for updates and inserts rather than the runtime generated versions. Then in your parsing code, simply call SubmitChanges without calling procUpdateInstructores manually. If your dbml is configured correctly, it will call the stored proc rather than the dynamic update statement.
Also, FWIW, your stored proc doesn't seem to be doing anything more than the generated SQL would. Actually, LINQ to SQL would give you more functionality since you aren't doing any concurrency checking in your stored proc anyway. If you are required to use stored procs by your DBA or some security policy, you can retain them, but you may want to consider bypassing them if this is all your stored procs are doing and rely on the runtime generated SQL for updates.

Categories