Table data insert from another table with an order sql - c#

In my project I need to insert a table data from another table. I trying to write this sql code. But this order by option is not working while inserting the data. Here is my code:
INSERT INTO StudentInfo_MeritPosition
( ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
)
SELECT ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
FROM StudentInfo
ORDER BY MeritPosition
The above code inserting data into database. But not in the order format.
I need to know if there any way our for this problem. Thank you.

SQL tables represent unordered sets. When you retrieve data from the table, the data has no particular order, unless you specify order by. So, you can just retrieve the data as:
select mp.*
from StudentInfo_MeritPosition mp
order by mp.MeritPosition;
You can make this query more efficient by adding an index on StudentInfo_MeritPosition(MeritPosition).

You can use a temp table to order in any way you want. In my opinion it's easier to assemble a temp table first, then order those results and select them into the table you're trying to populate in a given order. This way you can translate it to a stored procedure and feed it the parameter of "column name" and "ASC or DESC." The temp table will take a bit longer to work with since you're selecting, ordering, reselecting, and inserting. However, the end result is much more robust than a 1 time query allowing you to use any column name, and ASC or DESC. Just remember that when you do select the results into your permanent table, you leave out the primary key (typically [P_ID]) column form your select into statement.

So, to improve on Gordon's answer, you could write something like what follows:
DECLARE #fromTbl, #sortCol, #orderByCol VARCHAR(50)
EXEC('
select mp.*
from /* StudentInfo_MeritPosition* / ' + #fromTbl + 'mp
order by /* mp.MeritPosition */ mp.' + #orderByCol + ' ' + #sortOrder;'
/* If you wanted to debug it and make sure your parameters are being
generated correctly, you can use the PRINT function instead of
Exec('Your statement above') */
Then, if you turn it into a SP you can pass in the three parameters table, order by column, and sort order (ASC|DESC) and bypass the temp table creation process I mentioned previously.

Try this.
INSERT
/*+append*/
INTO StudentInfo_MeritPosition
( ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
)
SELECT *
FROM (
SELECT ID,
Name,
MeritPosition,
SSC,
HSC,
First,
Second,
Third,
Fourth,
Fifth
FROM StudentInfo
ORDER BY MeritPosition );

Related

how to find a particular string in the sentence and remove the string in sql

I have to remove the particular value from the sentence which is stored in SQL database. Sentence will look like this:
1 Payments:ihj - CHENNAI-HIRE:54005-TN69AZ54008,4021-TN69AZ54005
2 Payments:ihj - CHENNAI-HIRE:54004-TN69AZ54008,4021-TN69AZ54005,54005-TN69AZ54008
In above sentence 54004 is the number which I will pass as parameter to SQL. This is the number which I want to remove from this line but same number is present in this line as TN69AZ54005. This number should not be disturbed, and in another payment we have same amount in another place. Can anyone help on this?
I tried with this sql query
declare #text int=4019
select SUBSTRING(notes,CHARINDEX(cast(#text as varchar),notes),
len(notes)-CHARINDEX(',',notes)+1)
from Accounts.TransactionNotes
where TransactionID=1978
If I use this query it will affect including this line TN69AZ54005
I can see that you've included a C# tag into your question. Then probably the easiest way is just to select all necessary rows using your app, then iterate through them and change the strings to your needs (using eg. PHP preg_replace() equivalent) and update the SQL rows.
I believe that is the easiest way, not really SQL solution but still...
update <table> set notes = replace(notes, 'HIRE:'+ str(<inputparam>),'HIRE:') where transactionid=<transactionid>
update <table> set notes = replace(notes, ','+ str(<inputparam>),',') where transactionid=<transactionid>
You will need to find something to prefix your inputpram value, like in above example I am using "HIRE:" or a comma.
Another way could be to use REGEXP to find the whole word, then one one query would suffice. But I haven't tried it.
The problem here is not the query but the person who designed the
database.
I`m not sure is it this what you want but I will past my code. :)
-- for test create #temp
SELECT
A.DATA
INTO #Temp
FROM
(
SELECT 'Payments:ihj - CHENNAI-HIRE:54005-TN69AZ54008,4021-TN69AZ54005' AS DATA
UNION
SELECT 'Payments:ihj - CHENNAI-HIRE:54004-TN69AZ54008,4021-TN69AZ54005,54005-TN69AZ54008' AS DATA
) AS A
GO
-- this you want?
UPDATE #Temp
SET DATA = REPLACE(DATA,'54004','')
GO
-- select changed data
SELECT * FROM #Temp

SQL: How to check if all IDs in a list are in a table

first of all I am sorry if this question is too obvious, since I am quite new in SQL.
So, I have a list of IDs (variable, depending how many products the user chooses). And I want to check if all of them are in a table. If one of them is not, the result of the query should be null. If all of them are there, the result should be all the rows where those IDs are.
How can I do this?
Best regards,
Flavio
Do a LEFT JOIN from the list to the table on the ID field. You'll get a null if there is no record
You can even put a WHERE clause like 'WHERE List.ID IS NULL' to only see those that aren't in the table
Edit: Original Poster did not say they were using C# when I wrote this answer
UNTESTED:
Not sure if this is the most efficient but it seems like it should work.
1st it generates a count of items in the table for your list. Next it cross joins the 1 result record to a query containing the entire list ensuring the count matches the count in your provided list and limiting the results to your list.
SELECT *
FROM Table
CROSS JOIN (
SELECT count(*) cnt
FROM table
WHERE ID in (yourlist)) b
WHERE b.cnt = yourCount
and ID IN (YourList)
Running two in statements seems like it would be terribly slow overall; but my first step when writing SQL is usually to get something that works and then seek to improve performance if needed.
Get the list of Ids into a table, (you can pass them as a table variable parameter to a Stored proc), then in the stored proc, write
assuming the list of ids from C# is in table variable #idList
Select * from myTable
Where id in (Select id from #idList)
and not exists
(Select * from #idList
where id Not in
(Select id from myTable))

How can I find the row number of a particular row?

I have a database table like this:
I want to get the the row number of the second row. I use the following code:
SELECT ROW_NUMBER() OVER(ORDER BY Name) From Deposit WHERE Name='Murali'
But, its not working. Whats wrong with the code?
Thanks in advance.
The ROW_NUMBER function returns the row number in the resulting dataset.
In your query you restricted the results to only those whose name is Murali. Since you have only one such record, it is normal that it will return 1.
In SQL there's no such notion as row number. Table rows do not have an order. The notion of order only makes sense when you make a SQL query. Without SQL query you simply cannot talk about order and row numbers.
It appears that you need to introduce some order number for each user. The correct way to implement this is to add an Order column to your Deposit table. Now in order to retrieve it you would use the following query:
SELECT [Order] From Deposit WHERE Name = 'Murali'
All that's left is make the Order column to autoincrement and you are good to go. Everytime a new record is inserted the value will be automatically incremented. So there you go, now you have an order which represents the order in which the records have been inserted into the table. You now have context.
Perhaps something like this (if I understood you correctly):
SELECT Q.RN FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Name) AS RN, * From Deposit
) AS Q
WHERE Q.Name = 'Murali'
Try this
WITH TempTable AS
(
SELECT Name,ROW_NUMBER() OVER (ORDER BY Name) AS 'RowNumber'
FROM Deposit
)
SELECT RowNumber,Name
FROM TempTable
WHERE Name='Murali'

Where are the select query values stored temporarily and how to get each value separately

I have a stored procedure with a SELECT statement that outputs one row. It is something like this:
CREATE PROCEDURE [dbo].[CreateCustomer]
...
INSERT INTO Customers values(, , , ,)
SELECT CustomerID, FirstName, LastNam.....
INSERT Roles values(, , , .....
This selects the newly stored values back from the Customers table. The second insert uses the new CustomerID to insert a new row to the Roles table.
Is there a way to just get the customerID from the above select statement without querying again for the CustomerID?
I have tried to declare a variable and do it like this:
SELECT takenCustomerID = CustomerID, FirstName, LastNam....(rest of query statement)
But I have to declare all the variables and do it this way:
SELECT takenCustomerID, takenFirstName, takenLastNa... = CustomerID, FirstName, LastNam... (rest of query statement)
But, I think this is bad because it wastes lot of memory on the server side.
So, is there an easy way of getting individual values right away without declaring all the variables in the select statement, such as an inbuilt TEMP-like variable where I can call TEMP("customerID") and get that value?
Also, Can there be more than one SELECT statement in a stored procedure? How can we get the select values from the select statement we want?
I am asking more out of curiosity because I already know a way to get the value. I just want to know if there is a more elegant way.
Accessing Inserted Values
It is simple. Use the OUTPUT clause to return the values you just created.
DECLARE #Customers TABLE (
CustomerID uniqueidentifier,
FirstName varchar(100),
LastName varchar(100)
);
INSERT dbo.Customers
OUTPUT Inserted.*
INTO #Customers
SELECT newsequentialid(), #FirstName, #LastName, ...;
-- now you have all the values of the new row in the `#Customers` table variable.
Then you can do this:
INSERT dbo.Roles
SELECT
CustomerID,
#OtherValue,
#AnotherValue,
AnyotherColumnFrom#Customers
FROM #Customers;
If you have no further use for the values from the inserted Customer row, you could even do away with the table variable and just OUTPUT directly into the Roles table, assuming that all the values that go into that come from variables.
The OUTPUT clause gives access to the inserted values using the special meta-table Inserted. However, you can use variables and expressions with constants as well.
The good thing about using this method is that you can handle many inserted rows at once. If you are inserting only one row, you need only the CustomerID afterward, and you need to use it more than once, then instead do it this way:
DECLARE #CustomerID uniqueidentifier = newsequentialid();
INSERT #Customer VALUES (#CustomerID, ...);
INSERT #Roles VALUES (..., #CustomerID ...);
By creating the GUID in advance, you don't need to get it back out of the table. By the way, newsequentialid() is probably superior to newid() if it is the clustered index (which is probably true), because you will avoid the page splits that newid would cause.
Returning Multiple Result Sets
This is always possible. Whatever means you are using to query will have a method that advances your data access object to the next recordset. If you're using a DataReader then look into the NextResult method. In Classic ADO, recordsets have a NextRecordset method.
Unless you redirect it manually to a table, the SELECT will go only to the output stream, so no: you can't automatically access values from a previous select.
You might just be looking for SCOPE_IDENTITY():
declare #id int
insert ....
values (...)
set #id = SCOPE_IDENTITY()
In the general case of DML, another candidate is the OUTPUT clause.
For more general composite selects based on existing selects, a table-variable may help:
declare #foo table (id int not null, name nvarchar(100) not null) // etc
insert #foo (id, name)
select id, name from Foo where ...
select * from #foo // for output
// but we still have the #foo data available for subsequent query
... // more TSQL here
With multiple select statements, it depends entirely on what API you are using; however, the raw ADO.NET API here is IDataReader, which has the NextResult() method. Typical usage for multi-grid would be:
using(var reader = cmd.ExecuteReader()) {
do {
while(reader.Read()) {
// i.e. for each row in this grid
...
}
} while (reader.NextResult()); // <== for each grid
}
Note the difference between while(...) {...} and do {...} while(...) here is because you automatically start in the first grid, but you need to progress to the first row in that grid manually.

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