Linq to sql causing foreign key constraint errors - linq-to-sql

Here is the revelant code.
TournamentTeam newTeam = new TournamentTeam();
TournamentTeams.InsertOnSubmit(newTeam);
SubmitChanges();
TournamentParticipant newSignup = new TournamentParticipant
{
CheckedIn = false,
TournamentID = tournamentId,
UserID = participant.UserID,
TeamID = newTeam.TeamId
};
TournamentParticipants.InsertOnSubmit(newSignup);
SubmitChanges();
TournamentParticipants.TeamId has a fk relationship on TournamentTeam.TeamID, TeamID is an identity column
What I don't understand is that when TournamentTeam gets inserts, it grabs the new identity value. Even when I debug the code new Signup is recieving the new team id. But when it comes to generating the insert, it avoids this value completely and does the insert before the select statement where it grabs the new identity column.
exec sp_executesql N'INSERT INTO [dbo].[TournamentParticipants]([UserID], [TournamentID], [CheckedIn]) VALUES (#p0, #p1, #p2)
SELECT [t0].[TeamID] FROM [dbo].[TournamentParticipants] AS [t0] WHERE ([t0].[UserID] = #p3) AND ([t0].[TournamentID] = #p4)',N'#p0 int,#p1 int,#p2 bit,#p3 int,#p4 int',#p0=29805,#p1=247,#p2=0,#p3=29805,#p4=247
How can I either make linq to sql use the value for team id that I have specified or make the select statement be generated before the insert statement?

Instead of setting the TeamID, set the Team entity to the one you just created. Delay the SubmitChanges to insert both, then it will fix up the ids when the insert is done.
TournamentTeam newTeam = new TournamentTeam();
TournamentTeams.InsertOnSubmit(newTeam);
TournamentParticipant newSignup = new TournamentParticipant
{
CheckedIn = false,
TournamentID = tournamentId,
UserID = participant.UserID,
Team = newTeam
};
TournamentParticipants.InsertOnSubmit(newSignup);
SubmitChanges();

Related

update only null value columns in table if ID exits in table

I am trying to check for the ID. If it does not exist I want my data to be inserted as a new record in table and if ID exists I want to compare both incoming new record and existing record and only update the values which are null in existing record. I have written the query but I don't know how to check for null in each column:
Here is the query:
insert into ui_table(MDMID,FirstName,Lastname,Mail,Address,City,State,Zip,ProfileStatus,TAID)
select im.MDMID,im.FirstName,im.Lastname,im.Mail,im.Address,im.City,im.State,im.Zip,im.ProfileStatus,im.TAID
from intermediate im on duplicate key update
MDMID = im.MDMID,
FirstName = im.FirstName,
Lastname = im.Lastname,
Mail = im.Mail,
Address = im.Address,
City = im.City,
State = im.State,
Zip = im.Zip,
ProfileStatus = im.ProfileStatus,
TAID = im.TAID;

MVC with no Entity Framework

From the below source tutorials:
https://www.youtube.com/watch?v=Jt9vSY802mM
http://www.dotnetawesome.com/2017/07/curd-operation-on-fullcalendar-in-aspnet-mvc.html
How do I do the above code samples without Entity Framework, by just using SQL queries?
For example in the above source code, instead of
var v = dc.Events.Where(a => a.EventID == eventID).FirstOrDefault();
if (v != null)
{
dc.Events.Remove(v);
dc.SaveChanges();
status = true;
}
I want to do
DELETE FROM Even WHERE EventID = {0}
FirstOrDefault() in LINQ is equivalent to LIMIT 1 in MySQL, hence the LINQ function can be converted to SQL commands using IF or CASE WHEN like this (assumed commands are running inside a stored procedure):
DELIMITER //
-- 'Events' is a DbSet name by common convention,
-- therefore table name should be 'Event'
CREATE PROCEDURE procedure_name (IN eventID INT)
BEGIN
DECLARE v INT;
SET v = SELECT EventID FROM Event WHERE EventID = eventID LIMIT 1;
CASE WHEN v IS NOT NULL
THEN DELETE FROM Event WHERE EventID = v
ELSE -- do something else
END
-- alternative:
-- IF(v IS NOT NULL, DELETE FROM Event WHERE eventID = v, 0)
-- other stuff here
END//
DELIMITER ;
Note: If EventID is a primary key column, you can remove LIMIT 1 because query result only return single value.
Then, use CALL procedure_name(eventID) or include procedure_name in MySqlCommand to execute it.
Couple of ways:
using raw query in Entity Framework:
Open connection string via SqlConnection and execute:
Pseudo code for method 1:
string sqlDeleteStatement = "DELETE FROM Even WHERE EventID = #id";
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("#id", 1)); delete id = 1
_context.Database.SqlQuery(sqlDeleteStatement, parameterList);
Pseudo code for method 2:
using(SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = "Server=[server_name];Database=[database_name];Trusted_Connection=true";
string sqlDeleteStatement = "DELETE FROM Even WHERE EventID = #id";
SqlCommand command = new SqlCommand(sqlDeleteStatement , conn);
command.Parameters.Add(new SqlParameter("#id", 1)); //delete id = 1
command.ExecuteNonQuery();
}

UPDATE multiple rows with different values in one query in MySQL

I am trying to understand how to UPDATE multiple rows with different values and I just don't get it. The solution is everywhere but to me it looks difficult to understand.
For instance, three updates into 1 query:
UPDATE table_users
SET cod_user = '622057'
, date = '12082014'
WHERE user_rol = 'student'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '2913659'
, date = '12082014'
WHERE user_rol = 'assistant'
AND cod_office = '17389551';
UPDATE table_users
SET cod_user = '6160230'
, date = '12082014'
WHERE user_rol = 'admin'
AND cod_office = '17389551';
I read an example, but I really don't understand how to make the query. i.e:
UPDATE table_to_update
SET cod_user= IF(cod_office = '17389551','622057','2913659','6160230')
,date = IF(cod_office = '17389551','12082014')
WHERE ?? IN (??) ;
I'm not entirely clear how to do the query if there are multiple condition in the WHERE and in the IF condition..any ideas?
You can do it this way:
UPDATE table_users
SET cod_user = (case when user_role = 'student' then '622057'
when user_role = 'assistant' then '2913659'
when user_role = 'admin' then '6160230'
end),
date = '12082014'
WHERE user_role in ('student', 'assistant', 'admin') AND
cod_office = '17389551';
I don't understand your date format. Dates should be stored in the database using native date and time types.
MySQL allows a more readable way to combine multiple updates into a single query. This seems to better fit the scenario you describe, is much easier to read, and avoids those difficult-to-untangle multiple conditions.
INSERT INTO table_users (cod_user, date, user_rol, cod_office)
VALUES
('622057', '12082014', 'student', '17389551'),
('2913659', '12082014', 'assistant','17389551'),
('6160230', '12082014', 'admin', '17389551')
ON DUPLICATE KEY UPDATE
cod_user=VALUES(cod_user), date=VALUES(date)
This assumes that the user_rol, cod_office combination is a primary key. If only one of these is the primary key, then add the other field to the UPDATE list.
If neither of them is a primary key (that seems unlikely) then this approach will always create new records - probably not what is wanted.
However, this approach makes prepared statements easier to build and more concise.
UPDATE table_name
SET cod_user =
CASE
WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END, date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
You can use a CASE statement to handle multiple if/then scenarios:
UPDATE table_to_update
SET cod_user= CASE WHEN user_rol = 'student' THEN '622057'
WHEN user_rol = 'assistant' THEN '2913659'
WHEN user_rol = 'admin' THEN '6160230'
END
,date = '12082014'
WHERE user_rol IN ('student','assistant','admin')
AND cod_office = '17389551';
To Extend on #Trevedhek answer,
In case the update has to be done with non-unique keys, 4 queries will be need
NOTE: This is not transaction-safe
This can be done using a temp table.
Step 1: Create a temp table keys and the columns you want to update
CREATE TEMPORARY TABLE temp_table_users
(
cod_user varchar(50)
, date varchar(50)
, user_rol varchar(50)
, cod_office varchar(50)
) ENGINE=MEMORY
Step 2: Insert the values into the temp table
Step 3: Update the original table
UPDATE table_users t1
JOIN temp_table_users tt1 using(user_rol,cod_office)
SET
t1.cod_office = tt1.cod_office
t1.date = tt1.date
Step 4: Drop the temp table
In php, you use multi_query method of mysqli instance.
$sql = "SELECT COUNT(*) AS _num FROM test;
INSERT INTO test(id) VALUES (1);
SELECT COUNT(*) AS _num FROM test; ";
$mysqli->multi_query($sql);
comparing result to transaction, insert, case methods in update 30,000 raw.
Transaction: 5.5194580554962
Insert: 0.20669293403625
Case: 16.474853992462
Multi: 0.0412278175354
As you can see, multiple statements query is more efficient than the highest answer.
Just in case if you get error message like this:
PHP Warning: Error while sending SET_OPTION packet
You may need to increase the max_allowed_packet in mysql config file.
UPDATE Table1 SET col1= col2 FROM (SELECT col2, col3 FROM Table2) as newTbl WHERE col4= col3
Here col4 & col1 are in Table1. col2 & col3 are in Table2 I Am trying to update each col1 where col4 = col3 different value for each row
I did it this way:
<update id="updateSettings" parameterType="PushSettings">
<foreach collection="settings" item="setting">
UPDATE push_setting SET status = #{setting.status}
WHERE type = #{setting.type} AND user_id = #{userId};
</foreach>
</update>
where PushSettings is
public class PushSettings {
private List<PushSetting> settings;
private String userId;
}
it works fine

mysql update updating all user rows in table

Problem:
I have a mySql stored procedure which runs the following UPDATE:
IF target = 'sup' THEN
UPDATE my_table SET deleted = 1, last_updated = lastUpdate WHERE id = ID AND user_id = accountID;
END IF;
The input parameters are:
(IN ID BIGINT, IN lastUpdate DATETIME, IN target VARCHAR(3), IN accountID BIGINT)
When this sproc is called, mySql updates all of the rows in the table for the user_id and seems to ignore the id in the WHERE clause.
Background:
A mobile app makes an ajax json call to a .NET webservice, which then calls the mySql sproc.
The json call is like:
{"id":["5","6","10"],"lastUpdated":"2014-07-19 22:28:53","target":"sup","accountID":"309"}
At the .net webservice, it converts each id entry to Int64 and sends it to the mySql sproc:
For Each checkedID As String In id
cmd.Parameters.AddWithValue("#ID", CType(checkedID, Int64)).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#lastUpdate", dte).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#target", target).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#accountID", accountID).Direction = ParameterDirection.Input
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
Research and fix attempts:
Lots of search
Using MySQL Workbench; running the SQL directly correctly updates just the targeted row:
UPDATE my_table SET deleted = 1, last_updated = '1970-01-01 10:10:10' WHERE id = "7" AND user_id = 309;
However, if I call the sproc from within MySQL Workbench, it still updates all of the rows for the targeted user:
CALL `my_sproc`(7, '1990-01-01 10:10:10', 'sup', 309);
I cannot see anything wrong with the sproc, unless I've just looked at it for too long. The mobile app has got close to 100 MySQL sprocs, and this is the only one causing an issue.
I am stumped.
Just adding an explicit reference to the table fixed the issue.
my_table.id

Merge not inserting. No error

Can someone tell me why this insert is failing but not giving me an error either? How do I fix this?
merge table1 as T1
using(select p.1,p.2,p.3,p.4,p.5 from #parameters p
inner join table1 t2
on p.1 = t2.1
and p.2 = t2.2
and p.3 = t2.3
and p.4 = t2.4) as SRC on SRC.2 = T1.2
when not matched then insert (p.1,p.2,p.3,p.4,p.5)
values (SRC.1,SRC.2,SRC.3,SRC.4,SRC.5)
when matched then update set t1.5 = SRC.5;
The T1 table is currently empty so nothing can match. The parameters table does have data in it. I simply need to modify this merge so that it checks all 4 fields before deciding what to do.
You can't select from a variable: from #parameters
See the following post: Using a variable for table name in 'From' clause in SQL Server 2008
Actually, you can use a variable table. Check it out:
MERGE Target_table AS [Target]
USING #parameters AS [Source]
ON (
[Target].col1 = [Source].col1
AND [Target].col2 = [Source].col2
AND [Target].col3 = [Source].col3
AND [Target].col4 = [Source].col4
)
WHEN NOT MATCHED BY TARGET
THEN INSERT (col1,col2,col3,col4,col5)
VALUES (
[Source].col1
,[Source].col2
,[Source].col3
,[Source].col4
,[Source].col5
)
WHEN MATCHED
THEN UPDATE SET [Target].col5 = [Source].col5;