Mysql pdate query error - c#

I am trying to update my mysql table "upproj" using Visual Studio 2010 (c#).
I want to execute the following query :
string Query = " update tlog.upproj set summ=(select sum(grade) from tlog.upproj group by ams having count(*) =2); ";
But I get error
"You can't specify target table 'upproj' for update in FROM clause".
When I execute the previous query on Mysql Query browser I don't get any error, but my project needs to execute this query from visual studio.
Is there any way to fix that?

As the error hints at, you can't specify the table you're updating in the UPDATE statement's FROM clause (in the sub-query); the same is true if you were to try to use it in a WHERE clause.
You can accomplish the task of "using the table you're updating" if you use a JOIN though.
Based on the schema inferred by your existing query, the ams field is unique to a set grouping and you can, therefore, add that as part of your clause.
Try the following (untested):
UPDATE
tlog.upproj AS u1
JOIN (SELECT ams, SUM(grade) AS grade_sum FROM tlog.upproj GROUP BY ams HAVING COUNT(*) = 2) AS u2
ON u1.ams = u2.ams
SET
summ = u2.grade_sum;
This should update each record for ams with the total sum of grade for that same ams. If a specific ams doesn't have 2 entries, it isn't updated.

Related

Table is specified twice, both as a target for 'UPDATE' and as a separate source for data

I am trying to update multiple rows in a column but when I execute query getting error. Somebody guide me where I am wrong. Thanks in advance
UPDATE TestTaker
SET TestTaker.Email = 'Replaced'
WHERE TestTaker.Id IN (SELECT TestTaker.Id FROM TestTaker
INNER JOIN Questionnaire ON (TestTaker.id = Questionnaire.TestTaker_id)
WHERE Questionnaire.Project_id IN(SELECT Project.Id FROM Project WHERE NAME LIKE 'abcd'));
You are using table 'TestTaker' multiple times in that query, so you have to assign a 'alias' for that table and have to specify this alias for every columns wherever you using.
Or try to simplify your query like the below one.
UPDATE TestTaker
SET TestTaker.Email = 'Replaced'
WHERE TestTaker.Id IN ( SELECT Questionnaire.TestTaker_id
FROM Questionnaire
WHERE (TestTaker.id = Questionnaire.TestTaker_id)
AND Questionnaire.Project_id IN( SELECT Project.Id
FROM Project WHERE NAME LIKE 'abcd')
);

Visual Studio tableadapter configuration wizard failing to parse mysql statement

I have a MySQL statement which when executed in MySQL workbench, successfully returns a result. The statement in question is below:
SELECT report.*, client.`Client`, 3rdpartyreport.`Status` FROM report
LEFT JOIN client ON report.ClientID = client.ID
LEFT JOIN 3rdpartyreport ON (report.`Serial No` = 3rdpartyreport.`Serial No` AND report.`AssignedTo` = 3rdpartyreport.`Received By`)
WHERE (report.Status <> 'Deleted')
ORDER BY report.`Serial No` DESC
I am joining a column from the client table and the 3rdparty table to the report table. However, when I input this exact query into Visual Studio 2013 Dataset designer, it gives the error:
Error in join expression. Unable to parse query text.
As soon as I remove one of the LEFT JOIN lines, it works ok. Why doesn't Visual Studio allow multiple left joins? Am I doing something wrong, and if not then is there another way I can achieve the same result?
Figured it out. I needed to have 3rdpartyreport written as '3rdpartyreport', because it starts with a digit. Workbench doesn't need this apparently.

Trying to use Join to get data from two table into one query search using Join

I am issuing an SQL query in my visual studio application to search a database. I am having trouble joining two tables into one query search. I am looking to combine the First and Last name of an employee and match it up to a phone number. In one table I have an abbreviated name, and on the other table I have the full name.
Example
Code
cmdTxt.Append("SELECT partner.staffid, staff.Forename,staff.surname FROM tblpartner LEFT JOIN tblstaff ON staff.StaffID = partner.staffid ORDER BY staff.forename , staff.surname ");
I would Like to have a field that shows the Forename , surename, and phone number in one query search
You are using "partner" and "staff" as table aliases, but you aren't assigning those aliases to the table names. If you want to use those instead of the full table names, you need:
SELECT partner.staffid, staff.Forename,staff.surname, partner.phone
FROM tblpartner partner
LEFT JOIN tblstaff staff ON staff.StaffID = partner.staffid
ORDER BY staff.forename , staff.surname
As general advice, get your query working outside of your string literal; enter it into SQL Server Management Studio or something similar. Had you done that, it should have clearly showed you what the problem was. Then when you have your query set how you want, you can copy it into your Command Text in your Visual Studio application.

Linqer dont Convert T-Sql query

I using linqer want this sql to liqn query but i have problem
select * from Project where Id in (select Top 3 ForeignId from ActivityLog
group by ForeignId order by count(*) desc)
Problem :SQL cannot be converted to LINQ: Field [Id in (select Top 3 ForeignId from ActivityLog group by ForeignId order by count(*) desc)] not found in the current Data Context.
I just had a similar issue with linqer. I found the solution was removing the ; after the SQL query and trying again.
It could be an issue with your context.
See Linqer – a nice tool for SQL to LINQ transition for instructions on setting up the context.
Also, make sure the *.dbml and *.designer.cs files are up to date and define the Project table to contain an Id column and the ActivityLog table to contain a ForeignId column.
This could be a bug with the version of linqer you are using. I am using 4.0.3 and was able to run the same query (adjusted to use my tables) without issue.

How do I determine if I have execute permissions on a DB programatically?

I have a Windows Service that requires execute permissions on a SQL Server 2005 DB. On start up I check to see if I can connect to the DB and stop the service if I can't. I also want to do a check to see if I can execute a stored procedure using that connection. Is there a way to do that without actually attempting to execute a sproc and looking at the exception if one occurs?
SQL 2005 and on you can check any permission with HAS_PERM_BY_NAME:
SELECT HAS_PERMS_BY_NAME('sp_foo', 'OBJECT', 'EXECUTE');
you could run a query like this:
SELECT
o.NAME,COALESCE(p.state_desc,'?permission_command?')+' '+COALESCE(p.permission_name,'?permission_name?')+' ON ['+SCHEMA_NAME(o.schema_id)+'].['+COALESCE(o.Name,'?object_name?')+'] TO ['+COALESCE(dp.Name,'?principal_name?')+']' COLLATE SQL_Latin1_General_CP1_CI_AS AS GrantCommand
FROM sys.all_objects o
INNER JOIN sys.database_permissions p ON o.OBJECT_ID=p.major_id
LEFT OUTER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
where p.state_desc='GRANT' AND p.permission_name='EXECUTE'
AND o.NAME='YourProcedureName'
AND dp.Name='YourSecurityName'
...and remove the fancy formatting of the grant command, it is there only for reference
these are nice too...
SELECT * FROM fn_my_permissions('YourTable', 'OBJECT')
SELECT * FROM fn_my_permissions('YourProcedure', 'OBJECT')
SELECT * FROM fn_my_permissions (NULL, 'DATABASE')
SELECT * FROM fn_my_permissions(NULL, 'SERVER')
To see what permissions someone else has you can do this:
EXECUTE AS user = 'loginToTest'
GO
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id))+'.' + QUOTENAME(name)
,'OBJECT','SELECT'
) AS have_select
, *
FROM sys.tables;
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name)
,'OBJECT', 'EXECUTE') AS have_execute
, *
FROM sys.procedures;
GO
REVERT;
GO
The first part of this answer shows how you can check rights in T-SQL, the second part gives an example how to use this in the Entity Framework (note that there are differences between the EF versions - the example given is EF 4, but can be changed easily to a newer version):
First part (SQL):
I am using the following T-SQL script to check permissions. It first checks if you have any rights, then it checks execute permissions for the SPs, finally select permissions for the tables. See this link to get more information.
-- 1. Do I have any permissions?
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;
-- 2. create list of schemas
declare #SchemaList table (schema_id int, name nvarchar(max));
PRINT 'Schemas regarded:'
insert into #SchemaList
select distinct schema_id, name FROM sys.schemas
where name in ('dbo') -- enter the schemas you like to check comma-separated
SELECT s.name, s.schema_id FROM sys.schemas s
join #SchemaList sl on s.schema_id=sl.schema_id
-- 3. check execute permissions
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)
,'OBJECT', 'EXECUTE') AS [have execute]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.procedures t
join #SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
-- 4. check select permissions
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id))+'.' + QUOTENAME(t.name)
,'OBJECT','SELECT') AS [have select]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.tables t
join #SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
With the Northwind database for example, this gives you the following result:
Note that you can configure the schemas regarded in step 2. If you don't need a limited set of schemas checked, you can just comment out the where clause in the insert into #SchemaList statement to get all schemas.
Second part (Entity Framework):
In this section, I'd like to show you, how you can get the results into Entity Framework.
Let's suppose you want to check if you have any rights before using any of the tables in your LINQ queries. Take a look at this example (for simplicity, I've done it in LinqPad, please add System.Data.Entity.dll and its namespaces via F4 before you run it):
void Main()
{
var dc=this;
var sql="SELECT TOP 1 "
+ "HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;";
var result=dc.ExecuteStoreQuery<Rights>(sql);
if (result1.DoIHaveAnyRights==1)
{
Console.WriteLine("OK"); // ok
}
else
{
// no rights: Show error etc.
Console.WriteLine("No rights"); // ok
}
}
public class Rights
{
public Int32 DoIHaveAnyRights { get; set; }
}
Likewise you can use the query from the first part of my answer, e.g.:
var sql="select top 1 case when cnt.NoRightsCount=0 then 1 else 0 end "
+"as DoIHaveAnyRights "
+"from (SELECT count(1) NoRightsCount FROM sys.procedures t "
+"where HAS_PERMS_BY_NAME("
+"QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)"
+",'OBJECT', 'EXECUTE')<>1) cnt";
This query will check if there are any stored procedures in your database for which you have no rights to execute - in this case the return value would be result1.DoIHaveAnyRights!=1.
I think you get the idea, play around with the possibilities: Keep in mind that EF requires access to all the database tables, stored procedures etc. you're mapping to - you could use the code above to check before you access them. Unfortunately, there is currently no easier way to do this.
You would have to have rights to access the DataDictionary for your database and run a query against it to determine which permissions the account you log in with has. This would vary from database to database.

Categories

Resources