Running SQL Query from a SQL Query - c#

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

Related

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

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.

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

Batching Stored Procedure Commands in EF 4.2

I've got a call to a stored procedure, that is basically an INSERT stored procedure. It inserts into Table A, then into Table B with the identity from Table A.
Now, i need to call this stored procedure N amount of times from my application code.
Is there any way i can batch this? At the moment it's doing N round trips to the DB, i would like it to be one.
The only approach i can think of is to pass a the entire list of items across the wire, via an User Defined Table Type.
But the problem with this approach is that i will need a CURSOR in the sproc to loop through each item in order to do the insert (because of the identity field).
Basically, can we batch DbCommand.ExecuteNonQuery() with EF 4.2?
Or can we do it with something like Dapper?
You can keep it like that and in the stored procedure just do a MERGE between your target table and the table parameter. Because you are always coming with new records, the MERGE will enter only on the INSERT branch.
In this case, using MERGE like this is an easy way of doing batch inserts without a cursor.
Also, another way which also avoids the use of a cursor is to use a INSERT from SELECT statement in the SP.

Is it possible to insert data in to table through coding with out using table name

My question is generally we write the following through code while we are inserting data to a table
insert into tblname values('"+txt.text+"','"+txt1.text+"');
As we pass the data form the text boxes like that is it possible to insert in to table with out using table name directlty
Well you obviously need to know what table to insert into, so there has to be a table name identified to the INSERT statement. The options include:
an INSERT statement with actual table name as per your existing example
an INSERT statement with a synonym as the target (alias for an actual table - see: http://blog.sqlauthority.com/2008/01/07/sql-server-2005-introduction-and-explanation-to-synonym-helpful-t-sql-feature-for-developer/)
an INSERT statement with an updateable view as the target
a sproc call whereby the sproc knows the table to INSERT into (but the calling code does not need to know)
You should also be aware of SQL injection risks with your example - avoid concatenating values directly into a SQL string to execute. Instead, parameterise the SQL.
If you need to dynamically specify the table to insert into at run time, you have to concatenate the table name into the SQL statement you then execute. However, be very wary of SQL injection - make sure you fully validate the tablename to make sure there are no nasties in it. You could even check it is a real table by checking for it in sys.tables.
Not possible without name of table.
But you can make use of Linq To SQL (i.e any ORM) or DataAdapter.Update if you have filled it with the proper table....
You cannot do that without the table name, no. However, the bigger problem is that your code is horribly dangerous and at rick from SQL injection. You should fix this right now, today, immediately. Injection, even for internal apps, is the single biggest risk. Better code would be:
insert into tblname (Foo, Bar) values(#foo, #bar)
adding the parameters #foo and #bar to your command (obviously, replace with sensible names).
Before you ask: no, the table name cannot be parameterised; you cannot use
insert into #tblname -- blah
The table name(s) is(/are) fundamental in any query or operation.
I suppose that if it's possible you have to use parameters.
Here you have a little example.

C# database update

I'm stuck on a little problem concerning database.
Once a month I get a XML file with customer information (Name, address, city,etc.). My primary key is a customer number which is provided in the XML file.
I have no trouble inserting the information in the database;
var cmd = new SqlCommand("insert into [customer_info]
(customer_nr, firstname, lastname, address_1, address_2, address_3.......)");
//some code
cmd.ExecuteNonQuery();
Now, I would like to update my table or just fill it with new information. How can I achieve this?
I've tried using TableAdapter but it does not work.
And I'm only permitted to add one XML because I can only have one customer_nr as primary key.
So basically how do I update or fill my table with new information?
Thanks.
One way would be to bulk insert the data into a new staging table in the database (you could use SqlBulkCopy for this for optimal insert speed). Once it's in there, you could then index the customer_nr field and then run 2 statements:
-- UPDATE existing customers
UPDATE ci
SET ci.firstname = s.firstname,
ci.lastname = s.lastname,
... etc
FROM StagingTable s
INNER JOIN Customer_Info ci ON s.customer_nr = ci.customer_nr
-- INSERT new customers
INSERT Customer_Info (customer_nr, firstname, lastname, ....)
SELECT s.customer_nr, s.firstname, s.lastname, ....
FROM StagingTable s
LEFT JOIN Customer_Info ci ON s.customer_nr = ci.customer_nr
WHERE ci.customer_nr IS NULL
Finally, drop your staging table.
Alternatively, instead of the 2 statements, you could just use the MERGE statement if you are using SQL Server 2008 or later, which allows you to do INSERTs and UPDATEs via a single statement.
If I understand your question correctly - if the customer already exists you want to update their information, and if they don't already exist you want to insert a new row.
I have a lot of problems with hard-coded SQL commands in your code, so I would firstly be very tempted to refactor what you have done. However, to achieve what you want, you will need to execute a SELECT on the primary key, if it returns any results you should execute an UPDATE else you should execute an INSERT.
It would be best to do this in something like a Stored Procedure - you can pass the information to the stored procedure at then it can make a decision on whether to UPDATE or INSERT - this would also reduce the overhead of making several calls for your code to the database (A stored procedure would be much quicker)
AdaTheDev has indeed given the good suggestion.
But in case, you must insert/update from .NET code then you can
Create a stored procedure that will handle insert/update i.e. instead of using a direct insert query as command text, you make a call to stored proc. The SP will check if row exists or not and then update (or insert).
User TableAdapter - but this would be tedious. First you have to setup both insert & update commands. Then you have to query the database to get the existing customer numbers and then update the corresponding rows in the datatable making the Rowstate as Updated. I would rather not go this way.

Categories