I have a database table (Access Database) that contains data under OrderNo field.
When user enters new OrderNo, I want to check if that OrderNo already exists or not.
If so, a message should be displayed.
How can I do it using LINQ?
Thanks
Furqan
You could do something like this:
int searchOrderNo;
searchOrderNo = 123;
var q = from t in db.MyTable
where t.OrderNo.Equals(searchOrderNo)
select t.OrderNo;
if (q.Count() > 0)
{
MessageBox.Show("Value already exists");
}
Apologies, as you are using Access I think you will need to populate a DataSet and then use LINQ over the DataSet rather than querying the Access DB directly.
Related
In my Node batch-processor project I am using the mssql package, and I need to gather data from two different SQL databases and then basically emulate a merge operation. My question is, for SQL Server, is there a way I can use IN to pass in an array of IDs as part of the inner SELECT?
To clarify, the IDs I'll be passing in have been gathered from a separate query from a different SQL database. So what I need to do now is pass those IDs into this next query.
I've seen this kind of syntax:
SELECT DISTINCT Name
FROM Production.Product
WHERE ProductModelID IN
(SELECT ProductModelID
FROM Production.ProductModel AS pm
WHERE p.ProductModelID = pm.ProductModelID
AND Name LIKE 'Long-Sleeve Logo Jersey%');
GO
What would it look like to pass in those IDs as part of the inner SELECT statement? Is this something that can be done? Or is there a different way I should approach this?
And to clarify, I do need to do this within my Node project - so calling a stored procedure and using linked tables from my SQL Server database is not an option.
By the way, I could do something like this:
getMatchingIdRecords = async function() {
for (let sourceRecord of sourceArr) {
const matchingIdRecord = await sqlServerQueryHandler(`SELECT NoteDetailsId FROM SR_Empsheets
WHERE NoteDetailsId = ${sourceRecord.notes_detail_id}`);
if (matchingIdRecord) matchingIdRecords.push(matchingIdRecord);
}
return matchingIdRecords;
};
But this is less than ideal because I'm basically hitting the database for every record that is iterated through.
For SQL Server 2016+ you can pass a JSON Array to the query and parse it on the server. Something like:
SELECT NoteDetailsId FROM SR_Empsheets
WHERE NoteDetailsId in ( select value from openjson(#jsonArray) )
Where #jsonArray is a nvarchar(max) parameter that looks like
N'["1323","2311","1234"]'
I have a LinQ query which is intended to Update the table concerned.
The code is as follows:
LINQHelperDataContext PersonalDetails = new LINQHelperDataContext();
var PerDetails1 = (from details in PersonalDetails.W_Details_Ts
where details.UserId == userId
select details).First();
PerDetails1.Side = "Bridge";
PerDetails1.TotalBudget = 4000000;
PersonalDetails.SubmitChanges();
However, this change/update does not get reflected in the DB. Also,this does not throw any exception.Please suggest.
Make sure W_Details_Ts has one (or more) member properties marked as primary key. L2S can't generate update or delete statements if it does not know the underlying table's PK member(s).
I can't figure out if this is an acceptable operation. I need to select records from the SQL Server 2008 database and then delete them, all as a single transaction from an ASP.NET code. Note that the .NET code must be able to retrieve the data that was first selected.
Something as such:
SELECT * FROM [tbl] WHERE [id] > 6;
DELETE FROM [tbl] WHERE [id] > 6
I'm trying it with the SQL Fiddle but then if I do:
SELECT * FROM [tbl]
I get the full table as if nothing was deleted.
EDIT As requested below here's the full .NET code to retrieve the records:
string strSQLStatement = "SELECT * FROM [tbl] WHERE [id] > 6;" +
"DELETE FROM [tbl] WHERE [id] > 6";
using (SqlCommand cmd = new SqlCommand(strSQLStatement, connectionString))
{
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
//Read values
val0 = rdr.GetInt32(0);
val3 = rdr.GetInt32(3);
//etc.
}
}
}
This will do the select and delete simultanious:
delete from [tbl] output deleted.* WHERE [id] > 6
It is possible to select and delete in the same transaction as long as both operations are enlisted in the same transaction.
Look at this post
Transactions in .net
The "easiest" way to achieve transactions with a compatible provider (SQL Server works great!) is to use a TransactionScope. Just make sure the scope is created before the connection is opened so that everything is correctly enlisted.
The content of the SelectStuff and DeleteStuff methods doesn't matter much - just use the same connection, don't manually mess with the connection or with transactions, and perform the SQL operations however is best.
// Notes
// - Create scope OUTSIDE/BEFORE connection for automatic enlisting
// - Create only ONE connection inside to avoid DTC and "advanced behavior"
using (var ts = new TransactionScope())
using (var conn = CreateConnection()) {
// Make sure stuff selected is MATERIALIZED:
// If a LAZY type (Enumerable/Queryable) is returned and used later it
// may cause access to the connection outside of when it is valid!
// Use "ToList" as required to force materialization of such sequences.
var selectedStuff = SelectStuff(conn);
DeleteStuff(conn);
// Commit
ts.Complete();
// Know stuff is deleted here, and access selected stuff.
return selectedStuff;
}
The return value from multiple SQL statements is the result of the last statement run, which in this case is the DELETE. There are no rows returned from a DELETE, so there is nothing to read for val0 and val3.
There are two solutions I can think of here:
Change your code to expressly start a transaction, perform the SELECT, read the values, and then issue the DELETE, or
SELECT into a #temp table, execute the DELETE, and then SELECT from the #temp table, do what you need to with the rows, and then DROP th.
I don't actually want to modify either database, just get the data.
I know how to connect to each database individually, with these connection strings:
Provider=SQLOLEDB.1;Data Source={0};Initial Catalog={1};Integrated Security=SSPI;Persist Security Info=False;
Provider=OraOLEDB.Oracle.1;Data Source={0};User ID={1};Password={2};Persist Security Info=True;
But how can I get this overlapping data together? Is that even possible, especially considering that one is Oracle and one is SQL Server? Or would it be better to do the SELECT statements on each database individually and then match them after?
For example, how would I get all students that are 10 years old and like the color blue?
Notice that all items in DatabaseB have an ID that maps to DatabaseA, but not the other way around.
I have done this with MySQL,Oracle and SQL server. You can create linked servers from a central MSSQL server to your Oracle and other MSSQL servers. You can then either query the object directly using the linked server or you can create a synonymn to the linked server tables in your database.
Steps around creating and using a linked server are:
On your "main" MSSQL server create two linked servers to the servers that contains the two databases or as you said database A and database B.
You can then query the tables on the linked servers directly using plain TSQL select statements.
To create a linked server to Oracle see this link: http://support.microsoft.com/kb/280106
A little more about synonyms. If you are going to be using these linked server tables in a LOT of queries it might be worth the effort to use synonymns to help maintain the code for you. A synonymn allows you to reference something under a different name.
So for example when selecting data from a linked server you would generally use the following syntax to get the data:
SELECT *
FROM Linkedserver.database.schema.table
If you created a synonym for Linkedserver.database.schema.table as DBTable1 the syntax would be:
SELECT *
FROM DBTable1
It saves a bit on typing plus if your linked server ever changed you would not need to go do changes all over your code. Like I said this can really be of benefit if you use linked servers in a lot of code.
On a more cautionary note you CAN do a join between two table on different servers. HOwever this is normally painfully slow. I have found that you can select the data from the different server into temp tables and joining the temp tables can generally speed things up. Your milage might vary but if you are going to join the tables on the different servers this technique can help.
Let me know if you need more details.
Which database are you using? Most of databases come with concept called dblinks. You have to create a dblink of database B in database A and then you can create a synonym (not a must but for ease) and use it as if it is table of database A.
Looks like a heterogeneous join (data on disparate servers/technologies etc).
As such, not straightforward. If you can make Namphibian's method work, go that way.
Otherwise, you need to gather the data from both tables to a common location (one or other of the servers 'in play', or a third server/technology solely for the purpose of co-locating the data). Then you can join the data happily. Many ETL Tools work this way, and this situation (almost) always involves redistribution of one or more of the tables to a common location before joining.
Oracle Data Integrator ETL tool does this, so does Talend Open Studio's tJoin component.
HTH
Try creating 3 Linq queries in Visual Studio. One for SQL Server, one for Oracle and one to combine the 2 database objects.
SELECT (things)
FROM databaseA.dbo.table t1
INNER JOIN databaseB.dbo.table t2 ON t1.Col1 = t2.Col2
WHERE t1.Col1 = 'something'
EDIT - This statement should meet the new requirements:
SELECT *
FROM databaseA.dbo.table t1
INNER JOIN databaseB.dbo.table t2 ON t1.ID = t2.ID
WHERE t1.Age = 10 AND t2.FavoriteColor = 'Blue'
If you want to select data from two different servers and database I would do a union and not a join as the data from one may be like apples and the other may be like oranges. You still would need to set up linked Servers and I believe you may link Oracle and SQL Server if after certain versions as shown but you could do something like this:
select ColA, ColB, ColC
from (ServerASQLServer).(DatabaseA).(schema).(table)
UNION
select ColA, ColB, ColC
from (ServerBOracleServer).(DatabaseB).(schema).(table)
If you perform inner joins your data must share data types to bind to or else they will be ommitted from the dataset returned. A union must just shared column data types but does not care on the logic. You are in essence saying: "Put these two sets of varying rows together based on their column logic matching."
But you were mentioning connection strings so I was curious if you would want to do it in a type of code method like .NET? I could provide an idea for that too possibly.
Assuming the databases are on the same server, you should be able to do something like this:
SELECT t.field1, t.field2
FROM database.schema.table t
JOIN database2.scheme.table2 t2
on t.id = t2.id
WHERE t2.field3 = ...
If the databases are on separate servers, look into using Linked Servers.
While I was having trouble join those two tables, I got away with doing exactly what I wanted by opening both remote databases at the same time. MySQL 5.6 (php 7.1) and the other MySQL 5.1 (php 5.6)
//Open a new connection to the MySQL server
$mysqli1 = new mysqli('server1','user1','password1','database1');
$mysqli2 = new mysqli('server2','user2','password2','database2');
//Output any connection error
if ($mysqli1->connect_error) {
die('Error : ('. $mysqli1->connect_errno .') '. $mysqli1->connect_error);
} else {
echo "DB1 open OK<br>";
}
if ($mysqli2->connect_error) {
die('Error : ('. $mysqli2->connect_errno .') '. $mysqli2->connect_error);
} else {
echo "DB2 open OK<br><br>";
}
If you get those two OKs on screen, then both databases are open and ready. Then you can proceed to do your querys.
On your specific question I will do something like first selecting from database A all the 10 year old kids then match them to the colors by the ID from database B. It should work, I havent tested this code on my server, but my sample below this code works. You can custom query by anything, color, age, whatever, even group them as you require to.
$results = $mysqli1->query("SELECT * FROM DatabaseTableA where age=10");
while($row = $results->fetch_array()) {
$theColorID = $row[0];
$theName = $row[1];
$theAge = $row[2];
echo "Kid Color ID : ".$theColorID." ".$theName." ".$theAge."<br>";
$doSelectColor = $mysqli2->query("SELECT * FROM DatabaseTableB where favorite_color=".$theColorID." ");
while($row = $doSelectColor->fetch_assoc()) {
echo "Kid Favorite Color : ".$row["favorite_color"]."<br>";
}
}
I have use this to switch back and forth for our programs without joining tables from remote servers and have no problem so far.
$results = $mysqli1->query("SELECT * FROM video where video_id_old is NULL");
while($row = $results->fetch_array()) {
$theID = $row[0];
echo "Original ID : ".$theID." <br>";
$doInsert = $mysqli2->query("INSERT INTO video (...) VALUES (...)");
$doGetVideoID = $mysqli2->query("SELECT video_id, time_stamp from video where user_id = '".$row[13]."' and time_stamp = ".$row[28]." ");
while($row = $doGetVideoID->fetch_assoc()) {
echo "New video_id : ".$row["video_id"]." user_id : ".$row["user_id"]." time_stamp : ".$row["time_stamp"]."<br>";
$sql = "UPDATE video SET video_id_old = video_id, video_id = ".$row["video_id"]." where user_id = '".$row["user_id"]."' and video_id = ".$theID.";";
$sql .= "UPDATE video_audio SET video_id = ".$row["video_id"]." where video_id = ".$theID.";";
// Execute multi query if you want
if (mysqli_multi_query($mysqli1, $sql)) {
// Query successful do whatever...
}
}
}
// close connection
$mysqli1->close();
$mysqli2->close();
I was trying to do some joins but since I got those two DBs open, then I can go back and forth doing querys by just changing the connection $mysqli1 or $mysqli2
It worked for me, I hope it helps... Cheers
As long as both databases are in the same server you can refer to tables with the database name :)
SELECT * FROM db1.table1
join
db2.tbable2
WHERE db1.table1.col1 = db2.table2.col1;
Is it possible to return the last row of a table in MS SQL Server.
I am using an auto increment field for the ID and i want to get the last one just added to join it with something else. Any idea?
Here's the code:
const string QUERY = #"INSERT INTO Questions (ID, Question, Answer, CategoryID, Permission) "
+ #"VALUES (#ID, #Question, #Answer, #CategoryID, #Permission) ";
using (var cmd = new SqlCommand(QUERY, conn))
{
cmd.Parameters.AddWithValue("#Question", question);
cmd.Parameters.AddWithValue("#Answer", answer);
cmd.Parameters.AddWithValue("#CategoryID", lastEdited);
cmd.Parameters.AddWithValue("#Permission", categoryID);
cmd.ExecuteNonQuery();
}
Not safe - could have multiple inserts going on at the same time and the last row you'd get might not be yours. You're better off using SCOPE_IDENTITY() to get the last key assigned for your transaction.
using an auto increment field ... and i want to get the last one just added to join it with something else.
The key here is "just added". If you have a bunch of different users hit the db at the same time, I don't think you want user A to retrieve the record created by user B. That means you probably want to use the scope_identity() function to get that id rather than running a query on the table again right away.
Depending on the context you might also need ##identity (would include triggers) or ident_current('questions') (limited to a specific table, but not the specific scope). But scope_identity() is almost always the right one to use.
Here's an example:
DECLARE #NewOrderID int
INSERT INTO TABLE [Orders] (CustomerID) VALUES (1234)
SELECT #NewOrderID=scope_identity()
INSERT INTO TABLE [OrderLines] (OrderID, ProductID, Quantity)
SELECT #NewOrderID, ProductID, Quantity
FROM [ShoppingCart]
WHERE CustomerID=1234 AND SessionKey=4321
Based on the code you posted, you can do something like this:
// don't list the ID column: it should be an identity column that sql server will handle for you
const string QUERY = "INSERT INTO Questions (Question, Answer, CategoryID, Permission) "
+ "VALUES (#Question, #Answer, #CategoryID, #Permission);"
+ "SELECT scope_identity();";
int NewQuestionID;
using (var cmd = new SqlCommand(QUERY, conn))
{
cmd.Parameters.AddWithValue("#Question", question);
cmd.Parameters.AddWithValue("#Answer", answer);
cmd.Parameters.AddWithValue("#CategoryID", lastEdited);
cmd.Parameters.AddWithValue("#Permission", categoryID);
NewQuestionID = (int)cmd.ExecuteScalar();
}
See my answer to another question here:
get new SQL record ID
The problem now is that you'll likely want subsequent sql statements to be in the same transaction. You could do this with client code, but I find keeping it all on the server to be cleaner. You could do that by building a very long sql string, but I tend to prefer a stored procedure at this point.
I'm also not a fan of the .AddWithValue() method — I prefer explicitly defining the parameter types — but we can leave that for another day.
Finally, it's kind of late now, but I want to emphasize that it's really better to try to keep this all on the db. It's okay to run multiple statements in one sql command, and you want to reduce the number of round trips you need to make to the db and the amount of data you need to pass back and forth between the db and your app. It also makes it easier to get the transactions right and keep things atomic where they need to be.
use
scope_identity() returns the last identity value generated in this session and this scope
ident_current() returns the last identity value generated for a particular table in any session and any scope
select ident_current( 'yourTableName' )
will return the last identity created by a different session.
Most of the time you should use scope_identity() right after an insert statement like so.
--insert statement
SET #id = CAST(SCOPE_IDENTITY() AS INT)
MSDN Link - Scope_Identity()
MSDN Link - Ident_Current
select top 1 * from yourtable order by id desc
I'm not sure of your version of SQL Server, but look for the OUTPUT clause of ther INSERT statement. You can capture a set of rows with this clause
Since the questioner is using .NET, here's a modified example of how to do it. (I removed ID from the insert list since it's autoincrement--the original example would fail. I also assume ID is an SQL int, not a bigint.)
const string QUERY = #"INSERT INTO Questions (Question, Answer, CategoryID, Permission) "
+ #"VALUES (#Question, #Answer, #CategoryID, #Permission);"
+ #"SELECT #ID = SCOPE_IDENTITY();";
using (var cmd = new SqlCommand(QUERY, conn))
{
cmd.Parameters.AddWithValue("#Question", question);
cmd.Parameters.AddWithValue("#Answer", answer);
cmd.Parameters.AddWithValue("#CategoryID", lastEdited);
cmd.Parameters.AddWithValue("#Permission", categoryID);
cmd.Parameters.Add("#ID", System.Data.SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
int id = (int)cmd.Parameters["#ID"].Value;
}
EDITED: I also suggest considering LINQ to SQL instead of hand-coding SqlCommand objects--it's much better (faster to code, easier to use) for many common scenarios.
With a simple select you can do something like this:
SELECT *
FROM table_name
WHERE IDColumn=(SELECT max(IDColum) FROM table_name)