MySQL Multiple lines string puts 0 - mysql

I'm trying to insert a multiple line string into my MySQL db.
Example:
INSERT INTO `dressuurpaardje`.`Marks` (`markID`, `testID`, `markPosition`, `techinicalMark`, `directiveIdeas`, `maxMark`, `coefficient`, `overflow`)
VALUES (NULL, 1, 'M', 'Proceed in passage ' + CHAR(10) + CHAR(13) + ' Transition collected walk - passage', NULL, 10, NULL, NULL);
I use ' + CHAR(10) + CHAR(13) + ' with the intention to get a newline in the string. But this puts the string "0" in my db
Any suggestions?

Use '\n' in your query, and let the text interpreter add the line (depends what you use, but that's what I would recommend)
Use CONCAT(string1, CHAR(10), CHAR(13), string2), as mentionned also by Mazatwork.
Be aware that CHAR10 + CHAR13 is wrong. A line feed / carriage return is either:
chr10 or \n (unix)
chr13 + chr10 or \r\n (windows)

Related

Powershell: Unable to insert into MySQL date, int values with null

I have a MySQL table table_foo with columns col1 of type DATETIME ,col2 of type int, both accepts NULL values but when inserted from Powershell throws error.
$oMYSQLCommand.CommandText='INSERT into `table_foo` (`col1`,`col2`) VALUES("' + $null + '", "' + $null + '")'
$iRowsAffected=$oMYSQLCommand.ExecuteNonQuery()
also tried using [DBNull]::Value as ref in
$oMYSQLCommand.CommandText='INSERT into `table_foo` (`col1`,`col2`) VALUES("' + [DBNull]::Value + '", "' + $null + '")'
Error
Error: Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect datetime value: '' for column 'col1' at row 1"
Since you're constructing a string into which the null values are to be embedded, you must represent the null values using SQL syntax, which means: verbatim NULL (without surrounding single quotes):
$oMYSQLCommand.CommandText =
'INSERT into `table_foo` (`col1`,`col2`) VALUES (NULL, NULL)'
If the values come from PowerShell variables that are situationally $null and must therefore conditionally be translated to verbatim NULL, the best approach is to use a helper function, as demonstrated in this answer.
In the simplest case, with all variables containing strings, if you want to treat an empty string or a $null value as a SQL NULL,
you could define a function tf (short for: transform) as follows:
function tf ($val) {
if ([string]::IsNullOrEmpty($val)) { 'NULL' } else { "'{0}'" -f $val }
}
You could then use the function as follows, with $var1 and $var2 containing the values to embed:
$oMYSQLCommand.CommandText =
'INSERT into `table_foo` (`col1`,`col2`) VALUES ({0}, {1})' -f
(tf $var1), (tf $var2)
One more simple way of #mklement0's answer is. So the issue here is MySQL accepts variable values with quotes and NULL without quotes. If NULL in enclosed in quotes it is treated as string value. So while using variable concatenate quotes " if the variable value is not NULL
if($var_x -eq ""){$var_x ="NULL"}else{'var_x = '"'+ $var_x +'"'}
if($var_y -eq ""){$var_y ="NULL"}else{'var_y = '"'+ $var_y +'"'}
$oMYSQLCommand.CommandText='INSERT into `table_foo` (`col1`,`col2`) VALUES(' + $var_x + ',' + $var_y + ')'
$iRowsAffected=$oMYSQLCommand.ExecuteNonQuery()
try typing NULL, dont use variable:
VALUES('NULL','NULL')
something like this:
$oMYSQLCommand.CommandText="INSERT into `table_foo' (`col1`,`col2`) VALUES('NULL','NULL')"

SQL Server - OPENJSON error - JSON text is not properly formatted

Azure SQL Server 2017 -
We have a table dbo.MailArchive with a field called Mail_Body which contains the body of an email. The data always looks like this from record to record, just with different numbers, and Status message:
Status: Completed
Successful actions count: 250
Page load count: 250
But copy/pasting the above to test with will make it seem like there's no issue. YOu can use this to replicate the problem:
DECLARE #YourString varchar(8000) = 'Status: Completed
Successful actions count: 250
Page load count: 250' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10);
SELECT CONCAT('{"', REPLACE(REPLACE(#YourString, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}')
Further, this is what the body of the email looks like if I view it in Word with hidden characters turned on:
This is the format that the data gets exported to the database in.
I'm trying to use OPENJSON to parse this data by line break, as such:
SELECT Mail_Body,
j.*
FROM dbo.MailArchive d
CROSS APPLY OPENJSON (CONCAT('{"', REPLACE(REPLACE(d.Mail_Body, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}'))
WITH (
Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successfull actions count"',
Request_Count int '$."Request count"'
) j
I get the following error when executing this:
JSON text is not properly formatted. Unexpected character ',' is found
at position 246.
Based on some advice I've received thus far, I'm thinking it might have something to do with that line break at the end of the body. But I can't figure out the right syntax to account for it.
This is an expensive fix, as REVERSE isn't cheap, but you could use it and PATINDEX to find the first characters that aren't a line break or carriage return, remove them, and then parse that:
DECLARE #YourString varchar(8000) = 'Status: Completed
Successful actions count: 250
Page load count: 250' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10);
DECLARE #PI varchar(7) = '%[^' + CHAR(13) + CHAR(10) + ']%';
SELECT j.Status,
j.Successful_Actions_Count, --NULL as not in sample data
j.Request_Count --NULL as not in sample data
FROM (VALUES(#YourString))V(YS)
CROSS APPLY(VALUES(REVERSE(V.YS),PATINDEX(#PI,REVERSE(V.YS)))) PI(SY,I)
CROSS APPLY(VALUES(REVERSE(STUFF(PI.SY,1,PI.I,''))))S(FixedString)
CROSS APPLY OPENJSON (CONCAT('{"', REPLACE(REPLACE(S.FixedString, ': ', '":"'), CHAR(13) + CHAR(10), '","'), '"}'))
WITH (Status varchar(100) '$.Status',
Successful_Actions_Count int '$."Successfull actions count"',
Request_Count int '$."Request count"') j;
This assumes that there could be 0 to many sets of CHAR(13) + CHAR(10) at the end of the string. If it is only ever 2 sets, simply using SUBSTRING and LEN would be easier.

Using ltrim and rtrim in combination of substring

Hey there so I'm in the process of another project conversion there is a line written in Oracle SQL and I'm trying to convert it to MS SQL:
Oracle PL/SQL:
IF LTRIM(sCmtStr) IS NOT NULL THEN
sTrimStr := ' '||SUBSTR(RTRIM(LTRIM(sCmtStr),'; '),1,999);
ELSE
sTrimStr := NULL;
MS T-SQL:
IF ltrim(#sCmtStr) IS NOT NULL
SET #sTrimStr = ' ' + ISNULL(substring(rtrim(ltrim(#sCmtStr), '; '), 1, 999), '')
ELSE
SET #sTrimStr = NULL
I get the following error:
Msg 174, Level 15, State 1, Procedure TRIMCOMMENT, Line 12
The rtrim function requires 1 argument(s).
Any idea? Thank you.
RTRIM (https://learn.microsoft.com/en-us/sql/t-sql/functions/rtrim-transact-sql) Does not take 2 arguments; it can only trim spaces from the end of a string.
TRIM (https://learn.microsoft.com/en-us/sql/t-sql/functions/trim-transact-sql), on the other hand, can be given other characters to remove. It will remove the characters from both ends, however, so you might have to fiddle a bit if you only want it to remove from the end of the string.

Extracting Number From String SQL

I have a normal SQL statement:
SELECT VALUE_ID, UF_CRM_TASK FROM b_uts_tasks_task
Now this returns a a different field everytime but they take the form of the following:
a:1:{i:0;s:7:"CO_2012";} or a:1:{i:0;s:5:"CO_12";} or a:1:{i:0;s:7:"CO_2017";}
Basically they're different everytime. What I need is to just get the number after the CO_ part. I have tried TRIM but because everything changes in the leading and trailing section I don't think this would work.
I have looked on Stack Overflow for a while and cannot find it. I know how to do it in PHP:
$data = $row['UF_CRM_TASK'];
$companyID = substr($data, strpos($data, "CO_") + 1);
$newCompanyID = preg_replace('/[^0-9.]+/', '', $companyID);
But not SQL. Thanks in advance
In MYSQL is a bit ugly:
/*SUBSTRING_INDEX BASED ON CO_ AND THE LAST " - in 2 SUBSTRINGS*/
SELECT `VALUE_ID`, SUBSTRING_INDEX(SUBSTRING_INDEX(`UF_CRM_TASK`, 'CO_', -1), '"', 1) AS `COMPANY_ID` FROM `b_uts_tasks_task`
In PHP you can just unserialize():
$data = unserialize($row['UF_CRM_TASK']);
$companyID = str_replace('CO_', '', $data[0]);
eg:
$data = unserialize('a:1:{i:0;s:5:"CO_12";}');
echo str_replace('CO_', '', $data[0]);
//==> 12
You need to use CharIndex and SubString (Microsoft SQL) or
This is the sample code I made for my Microsoft SQL server:
declare #companyIdString varchar(50) = 'a:1:{i:0;s:7:"CO_2012";}'
print 'Company ID in a string: ' + #companyIdString
print 'Find first position: ' + Cast(charindex('"CO_', #companyIdString) as varchar(2))
print 'Locate the second position (the last "): ' + Cast(charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) as varchar(2))
print 'Extracted Company Id: ' + substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4)
select
#companyIdString as CompanyIdString,
substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4) as CompanyId
I also made the same code on a mySQL server:
set #companyIdString := 'a:1:{i:0;s:7:"CO_2012";}';
select
#companyIdString as CompanyIdString,
substring_index(substring_index(substring_index(#companyIdString, '"', 2), '"', -1), '_', -1) as CompanyId
The substring_index starts by locating the second " (string is now a:1:{i:0;s:7:"CO_2012), then it searches backward with the -1 to locate the first " (string is now CO_2012). And then it searches backward for the underscore (string is now 2012).

What is SQL Server function to concatenate with separator [duplicate]

This question already has answers here:
CONCAT_WS() for SQL Server
(6 answers)
Closed 8 years ago.
I am looking for SQL Server equivalent of MySQL concat_ws to concatenate strings with separator. I could not find one, is there a single function in SQL server to achieve this task?
There is no real equivalent (even the referenced answer is not exactly equivalent). You would normally add the separators between each value:
select A + ',' + B + . . .
One primary difference is that concat_ws() will skip NULL arguments, but + will not. You could emulate this behavior with:
select stuff((coalesce(',' + A, '') + coalesce(',' + B, '') + . . .
), 1, 1, '')
Of course, this doesn't convert the values to strings, as concat_ws() does. So, a closer version is something like:
select stuff((coalesce(',' + cast(A as varchar(255)), '') +
coalesce(',' + cast(B as varchar(255)), '') +
. . .
), 1, 1, '')
You can apply the same fixes to the referenced answer:
SELECT id,
STUFF((SELECT ';' + cast(v as varchar(255))
FROM (VALUES (a), (b), (c), (d)) AS v (v)
WHERE v is not null
FOR XML PATH (''), TYPE
).value('.[1]', 'varchar(max)'),
1, 1, ''
)
FROM foo
ORDER BY id;