I can't create Link Server to MySQL in SQL Server - mysql

I am trying to access data stored on MySQL from SQL Server.
I have followed the instructions on this site
http://www.sqlservercentral.com/Forums/Topic340912-146-1.aspx
I created the linked server with no problems but when I tried to select data using OPENQUERY I get the following Error
Msg 7357, Level 16, State 2, Line 1
Cannot process the object "
SELECT
CAST(t.name AS CHAR) AS team_name,
CAST(TRIM(REPLACE(CONCAT(su.first_name, " ", su.middle_name , " ", su.last_name), " ", " ")) AS CHAR) AS fullname,
CAST(su.login_user AS CHAR) AS username,
CAST(t.billing_department_id AS UNSIGNED) AS billing_dept_id
FROM my_table.users AS su
INNER JOIN my_table.teams AS t ON t.team_id = su.team_id
WHERE client_id = 1 ". The OLE DB provider "MSDASQL" for linked server "SQLSERVER_1" indicates that either the object has no columns or the current user does not have permissions on that object.
This is my query
SELECT * FROM OPENQUERY(SQLSERVER_1, '
SELECT
CAST(t.name AS CHAR) AS team_name,
CAST(TRIM(REPLACE(CONCAT(su.first_name, " ", su.middle_name , " ", su.last_name), " ", " ")) AS CHAR) AS fullname,
CAST(su.login_user AS CHAR) AS username,
CAST(t.billing_department_id AS UNSIGNED) AS billing_dept_id
FROM my_table.users AS su
INNER JOIN my_table.teams AS t ON t.team_id = su.team_id
WHERE client_id = 1 ') AS su
Can somebody tell me what is wrong with this, what can I do to fix this error?
Thanks

I finally solved the problem. The solution is very silly but I can't belive it was the solution. The solution is to simple Remove the space between the MySQL select and the single quote. so it becomes 'SELECT CAST(t.name AS CHAR) AS team_name, ........

I was having the same problem but not until after we upgraded to the MySQL ODBC 5.3 driver. Since we had a lot of existing queries with a new line I spent some time trying to find a fix. Turns out the problem was caused by using the unicode version of the driver. Once I switched to ANSI the problem went away.

Related

Query is working in MySQL 5.6 but not MySQL 5.7

I have 2 applications in Google Apps Script. They both have the exact same coding and data in the database. One of them runs version 5.6 in MySQL (which is the one that's working). The other run runs off of version 5.7 in MySQL. The query is exactly the same for both Scripts but the one running version 5.6 is not filling the table with the rows all the way. Its acting as if there is a limit setting somewhere that needs to be changed. It will just stop and not calculate the total.
SELECT DISTINCT dp.id, dp.`driver_code`, CONCAT(tdr.first_name, ' ', tdr.last_name) AS driver_name,
GROUP_CONCAT(
dp.ivh_invoicenumber, ':', dp.`as_code`, ':', DATE(sih." + SETTINGS.INV_PAY_ORDER + "), ':',
CONCAT(sih.shipper_city, ', ', sih.shipper_state), ':',
CONCAT(sih.consignee_city, ', ', sih.consignee_state), ':',
asl.`description`, ':', dp.pay, ':', dp.paid
ORDER BY sih." + SETTINGS.INV_PAY_ORDER + " SEPARATOR '|'
) AS invoices
FROM DriverPay AS dp
JOIN `tptdrivr` as tdr
ON tdr.`driver_code` = dp.`driver_code`
JOIN `Salisbury_invoiceheader` AS sih
ON sih.`ivh_invoicenumber` = dp.`ivh_invoicenumber`
JOIN tptasssr AS asl
ON asl.`as_code` = dp.`as_code`
WHERE dp.paid < 2 " + pDates + "" + terminal + "
GROUP BY dp.`driver_code`
ORDER BY dp.`driver_code` ;
I have attached a snippet that shows what the outcome is for the script running MySQL 5.7.3. Is there a setting I need to change somewhere? Any advice would be greatly appreciatedimage of issue

Using SSIS to query ADO .NET source query passing in parameters from SQL Server

I would like to pass parameters to a MySQL query using ado.net as the source of the query.
SELECT *
FROM userinfo
WHERE load_date > '2012-01-07'
AND load_date < '2012-01-14'
I have a settings table in sql server that has my values:
SELECT startdate, enddate
FROM tblsetting
I have managed to pass these values into SSIS. If I run a query against my sql server tables I am able to use this:
SELECT *
FROM userinfo
WHERE load_date > ?
AND load_date < ?
But when I change my source to ado.net, connecting to mysql server , it does not like that syntax. Can anyone explain what am I missing?
You can write a SQL expression and store it a variable of type String
"SELECT *
FROM userinfo
WHERE load_date > '" + (DT_WSTR,20) #[User::YourDateTimeVar] + "''
AND load_date < '" + (DT_WSTR,20)#[User::YourDateTimeVar] + " ' "
and then use this variable for a property which is present in the expression of Data Flow Task .Write click on DFT and select Properties . Click on Expression and select Ado.NET sql command from the properties in the dialogue box
Select the variable for the above property.Here ADO_SRC_Orale[SqlCommand] property will be replaced by the name of your ADO.NET source

same SQL concatenation opeartor for mysql,mssql,oracle

I am trying to use same sql statement for the above three DBMS .. but the problem is that it has string concatenation involved but there are different ways in each dbms for concatenation operation .. but i want the single operator .. Need someone's help
You can perhaps get around this in your application code by using a placeholder for concatenation in your sql statements, and then replacing it with the correct style for the rdbms you are using:
select {conpre} myfield1 {conmid} myfield2 {conmid} myfield3 {conend}
from mytable
Then in pseudo-code:
if rdbms is sqlserver
conpre = ""
conmid = " + "
conend = ""
else if rdbms is mysql
conpre = "concat("
conmid = ", "
conend = ")"
else if rdbms is oracle
conpre = ""
conmid = " || "
conend = ""
else if
' etc...
end if
stmt = replace(stmt, "{conpre}", conpre)
stmt = replace(stmt, "{conmid}", conmid)
stmt = replace(stmt, "{conend}", conend)
I'd avoid writing your own solution to the problem and use one of the muti-database tools already available. If you have come across this problem once you will come across it again soon.
I've no affiliation with the following but you could try Datanamic Multirun
The simple answer is to the question seems to be no.
However...
What if you create the package dbo in Oracle?
Is it not also possible in mysql to create a function called concat in a separate database called dbo, so that a function is called using the syntax dbo.concat(a, b, c)?
Unfortunately, mysql doesn't support default parameters(unless recently changed) or function overloading, so you would have to create on function for each number of arguments:
concat2(s1, s2)
concat3(s1, s2, s3)
and so on.
There is a way of doing this using ODBC escape sequences
SELECT {fn concat (col1, {fn concat (col2, col3)})}
FROM YourTable
From my current understanding this will work fine in SQL Server and MySQL but for Oracle is dependant upon connection method.
MySQL:
SELECT CONCAT('New ', 'York ', 'City');
Output is : New York City
Oracle:
SELECT 'The city' || ' is ' || 'Paris' FROM dual;
Output is : The city is Paris
SQL Server:
SELECT 'The city' + ' is ' + 'Paris';
Output is : The city is Paris
SELECT CONCAT('The city', ' is ', 'Paris');
Output is : The city is Paris

convert mssql query to mysql query

I have the following mssql query that I found on the net that is supposed to help me with a complex mysql query that I have been struggling with for a few days now.
SELECT
inv.typeID AS typeID,
inv.typeName AS typeName,
invGroups.groupName AS groupName,
inv.published AS published,
inv.description AS description,
rankVal.valueFloat AS rank,
replace (( SELECT skills.attributeName AS [data()]
FROM dgmTypeAttributes tattr -- Link between skillbook and attributes
INNER JOIN dgmAttributeTypes skills ON (skills.attributeID = tattr.valueInt)
WHERE (tattr.typeID = inv.typeID)
AND (tattr.attributeID IN (180, 181)) -- Primary and secondary attributes
ORDER BY inv.typeID FOR xml path('')), ' ', ',') AS prisec,
replace (( SELECT RTRIM(CAST(inv2.typeID AS varchar)) + ',' AS [data()]
FROM (SELECT * FROM dgmTypeAttributes WHERE (attributeID in (182, 183, 184)) -- Pre-req skills 1, 2, and 3
AND (typeID = inv.typeID)) tattr2
INNER JOIN invTypes inv2 ON (tattr2.valueInt = inv2.typeID)
ORDER BY inv.typeID FOR xml path('')), ' ', ' ') AS prereq,
replace (( SELECT RTRIM(CAST(tattr2.valueInt AS varchar)) + ',' AS [data()]
FROM (SELECT * FROM dgmTypeAttributes WHERE (attributeID in (277, 278, 279)) AND (typeID = inv.typeID)) tattr2 -- Link between skillbook and attributes
ORDER BY inv.typeID FOR xml path('')), ' ', ' ') AS prereqlvl
FROM invTypes inv
INNER JOIN invGroups ON (inv.groupID = invGroups.groupID)
INNER JOIN dgmTypeAttributes rankVal ON (inv.typeID = rankVal.typeID)
WHERE invGroups.categoryID = 16 -- Skillbooks category
AND rankVal.attributeID = 275 -- Skill rank attribute
AND inv.published = 1
GROUP BY inv.typeID, inv.typeName, invGroups.groupName, inv.published, inv.description, rankVal.valueFloat
ORDER BY invGroups.groupName, inv.typeName
I am so so with mysql but I know nothing of mssql. Can somebody recommend a good method of converting this query that is low or now cost? I do not expect somebody to convert it for me as that would be asking too much, but some suggestions that would point me in the rite direction (aside from learning mssql lolz) would be very nice. Thank you for your time and patience.
'Recommendation: extract the data out of you MySQL database in a delimited file (csv) using the utf8 (unicode) character set. Import into SQL Server using bcp specifying utf8 with "-Jutf8" parameter and character mode "-c".' See this site. Also, there's a nice tool for this.
Those subqueries with FOR XML PATH('') seem to be used to concatenate strings1. See if you can replace them with GROUP_CONCAT in MySQL. The other bits seem to be standard SQL.

SQL Server Agent - Can Job Ask Information About Itself

I don't suppose anyone knows whether a SQL Server Agent Job can ask information about itself, such as its own ID, or the path it's running from? I'm aware of xp_sqlagent_enum_jobs and sp_help_job but this doesn't help, because you have to specify the job ID.
The idea is that we want code that we don't have to manage by being able to call a sproc which will identify the current job. Any ideas?
Yes, but it isn't pretty.
Look at the sys.sysprocesses (or dbo.sysprocesses in SQL 2000 and below). The program name will be SQL Agent something with a binary value at the end. That binary value is the binary vale of the guid of the job. So, substring out that value and do a lookup against the msdb.dbo.sysjobs table to find out what job it is (you'll need to cast the sysjobs.job_id to varbinary(100) to get the values to match).
I told you it wasn't pretty, but it will work.
nasty!!! but i think it might work...
eg. used within a job - select * from msdb..sysjobs where job_id = dbo.fn_currentJobId()
let me know.
create function dbo.fn_CurrentJobId()
returns uniqueidentifier
as
begin
declare #jobId uniqueidentifier
select #jobId = j.job_id
from master..sysprocesses s (nolock)
join msdb..sysjobs j (nolock)
on (j.job_id = SUBSTRING(s.program_name,38,2) + SUBSTRING(s.program_name,36,2) + SUBSTRING(s.program_name,34,2) + SUBSTRING(s.program_name,32,2) + '-' + SUBSTRING(s.program_name,42,2) + SUBSTRING(s.program_name,40,2) + '-' + SUBSTRING(s.program_name,46,2) + SUBSTRING(s.program_name,44,2) + '-' + SUBSTRING(s.program_name,48,4) + '-' + SUBSTRING(s.program_name,52,12) )
where s.spid = ##spid
return #jobId
end
go
thanks for the info though