Insert multiple nodes to xml field in single query - sql-server

I'm having a table (let's call her t) that contains the fields id(int) and XmlField(xml).
I try to add multiple node in one query but no matter what I tried I keep getting errors.
The query is:
update t
set XmlField.modify('insert <f1>value here</f1><f2>value there</f2> into (/xmldoc)')
and I getting the error:
XQuery [t.XmlField.modify()]: Syntax error near '', expected 'as', 'into', 'before' or 'after'.
When I trying to add only one xml node it's working (example):
update t set XmlField.modify('insert <f1>value here</f1> into (/xmldoc)')
it's also working when I try to add nested nodes like this:
update t set XmlField.modify('insert <f><f1>value here</f1><f2>value there</f2></f> into (/xmldoc)')
Is there any way to make it happen?

The SQL Server documentation does say pretty clearly that the insert statement can handle multiple nodes. So my guess is that your problem is just a syntax error. (The Microsoft syntax varies slightly from that defined in the XQuery Update Facility spec, but it's recognizably similar.)
I'd try making the elements f1 and f2 into a sequence and wrapping them in parentheses (the spec requires an ExprSingle here, which means no top-level commas are allowed):
update t
set XmlField.modify(
'insert (<f1>value here</f1>, <f2>value there</f2>) into (/xmldoc)')
(Not tested against SQL Server.)

Related

Replace is not working for weird character

I use UPDATE a SET GR_P = REPLACE(GR_P,'','') FROM mytable a to replace things.
But replace function is not working for below charter:
In Query analyzer it works but when I used SSIS Execute SQL task or OLEDB Source then it is giving me error:
No Connection manager is specified.
In Toad against Oracle (since that's one of your tags), I issued this (pressing ALT-12 to get the female symbol) and got 191 as a result. note selecting it back using CHR(191) shows an upside-down question mark though.
select ascii('♀') from dual;
Given that, this worked but it's Oracle syntax, your mileage may vary.
UPDATE mytable SET GR_P = REPLACE(GR_P, CHR(191));
Note if it does not work, that symbol could be for another control character. You may need to use a regular expression to eliminate all characters not in a-zA-Z0-9, etc. I suspect you'll need to update your tags to get a more accurate answer.
Maybe this info will help anyway. Please post back what you find out.

Msg 8152, Level 16, State 10 on Like where clause

Might get some negative points here but feel the need to post an problem (And self-defined solution) that I could not match to anything on the interweb...
I have a very simple bit of code that returns the queries that my company's SSRS RDL datasets uses to obtain data.
It works nicely when returning all data, but the moment I add a where clause to only return records with specific text within the data set like the parameter I get an error:
Msg 8152, Level 16, State 10 ...
String or binary data would be truncated
The parameter is defined exactly the same as the column I am searching in is (NVARCHAR(MAX)).
I know what that error means ("The error means that you're trying to put a value into a table that is larger than what the column can hold. I.e. you're to insert a varchar(100) into a column that's been defined as varchar(80).") but what stumped me was that the flippen thing only errors out when run the query with the where clause.
I managed to narrow the culprit record down to one having 12351 characters (Using LEN).
The solution that I found was to change the LIKE to an =. Not 100% ideal because I would like the flexibility to search for any text within the column, but I can live with it.
If you are using LIKE operator in following manner:
WHERE myColumn LIKE '%some text%`
which I suspect you do from your description:
to search for any text within the column
Then, you can replace it with WHERE CHARINDEX('some text', myColumn) > 0 and see if it will work.

Assigning value from single row result set in ssis giving error in SSIS 2012

I am trying to get CSV IDs from a table from sql server and assign the result to a variable. below is the sql I have put inside the Execute SQL Task
set nocount on
declare #csv varchar(max) = ''
select #csv = #csv + cast(companyid as varchar(10)) + ',' from company where isprocessed = 0
select substring(#csv,1,len(#csv) - 1) as companyids
As you can see its a simple and standard way of getting csv of a field in t-sql. It works perfectly in query window but throwing below error when I run the Task in SSIS 2012
[Execute SQL Task] Error: The value type (__ComObject) can only be
converted to variables of type Object.
[Execute SQL Task] Error: An error occurred while assigning a value to
variable "sCSVCompanyIds": "The type of the value (DBNull) being
assigned to variable "User::sCSVCompanyIds" differs from the current
variable type (String). Variables may not change type during
execution. Variable types are strict, except for variables of type
Object. ".
Below are the settings of Execute SQL Task
In General tab, Resultset project is set to single row
In Result Set tab, Result Name is set to 0 (I also tried by setting it to csvids which is the alias column name in the select list) and Variable Name is set to User::sCSVCompanyIds
I have no clue why its not working. After wasting so much time I am worked out a hard way which by returning the result as Full Row set (same SQL which returns 1 row 1 column always) and add a for each loop container to loop throw the result set (which will always iterates only once for obvious reasons) and assign the result set's fields to the variable. It works for me but there should be easy way of doing it. What I am missing?
The problem is with the nvarchar(max) data type. I assume it will be same for varchar(max) also. Though relevant data types in SSIS are DT_NTEXT and DT_TEXT are present for some reason we are getting this error.
There are multiple options to handle this.
One Of course there might be more appropriate way to handle this by cast/converting the column within the query to fixed length instead of max something like cast(myvarcharmaxfield as varchar(8000)). In my case it doesn't work because I expect bigger length string. I am generating a csv string from a unique identifier column which itself is 36 chars long string and needs 3 extra chars for quoting them with signle quote and a comma as separator which will support only 205 values. So it doesn't work for me.
So I left with no option but to stick the way I implemented already which is in my question
After wasting so much time I am worked out a hard way which by
returning the result as Full Row set (same SQL which returns 1 row 1
column always) and add a for each loop container to loop throw the
result set (which will always iterates only once for obvious reasons)
and assign the result set's fields to the variable
The new way I learnt is from an unaccepted answer from this question
Change the Oledb connection to ADO.NET connection
I think this is fair enough but it requires me to create another connection manager (so that I don't have to change all existing tasks) and use it for this type of taks where I need csv but I did not buy it as I have very little time to doing research on creating connection string of it which appears to me with the type of erros I am getting is different from oledb.

ColdFusion 10 error with Stored Procedures

In a .CFC file, within a CFfunction and with CFargument tags.
<cfscript>
var sp=new storedproc();
sp.setDatasource(variables.datasource);
sp.setProcedure("storedProcedure_INSERT");
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.one);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.two);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.three);
sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.four);
sp.addProcResult(name="results",resultset=1);
//writeDump(sp);break; //This dump is reached
var spObj=sp.execute(); //blows up here; this is never reached
writeDump(spObj);break; //This is never reached, either.
var spResults=spObj.getProcResultSets().results;
A shiny nickle to anyone who can tell me why the sp.execute() is blowing up with message
"Cannot find results key in structure.
The specified key, results, does not exist in the structure."
I've used this psuedo-code many, may times in the past, and never had it do this. I'm connected to a MSSQL Server 2012 DB, everything's cricket in CF Admin, and other SPs are working properly. The stack trace doesn't even include any of MY code at all o_O
The error occurred in C:/ColdFusion10/cfusion/CustomTags/com/adobe/coldfusion/base.cfc: line 491
Called from C:/ColdFusion10/cfusion/CustomTags/com/adobe/coldfusion/storedproc.cfc: line 142
Called from //hq-devfs/development$/websites/myProject/cfc/mySOAPWSDLs.cfc: line 123
And SO is blowing up if I try and paste anymore of that. Google has...not been helpful ._.
Short answer: The error means you are trying to retrieve a resultset from the stored procedure, when it does not actually return one. A simple solution is to add a SELECT to the end of your procedure, so it returns a resultset containing the data you need. Then your original code will work:
SELECT ##ROWCOUNT AS NumOfRowsAffected;
Longer answer:
The method you are using, addProcResult(), is the equivalent of <cfprocresult>. It is intended to capture a resultset returned from a stored procedure. (Due to CF's poor choice of attribute names, a lot of people think "resultset" means the storedproc "result" structure, but they are two totally different things). A "resultset" is a query object", in CF parlance.
While all four (4) of the primary sql statements return some result, not all of them return a "query object"
Only SELECT statements generate a "query object"
INSERT/UPDATE/DELETE statements simply return the number of rows affected. They do not generate a "query object".
Since your stored procedure performs an INSERT, it does not generate a "query object". Hence the error when you try and grab the non-existent query here:
sp.addProcResult(name="results",resultset=1);
The simple solution is to add a SELECT statement to the end of your stored procedure, so that it does return a query object. Then your code will work as expected.
As an aside, I suspect you were actually trying to grab the "result" structure, but used the wrong method. The equivalent of <cfstoredproc result=".."> is getPrefix(). Though that would not work here anyway. According to the docs, it does not contain the number of rows affected. Probably because stored procedures can execute multiple statements, each one potentially returning a row count, so there is not just a single value to return.

sql query replace all specific values with a different value

I am attempting to replace specific values in one column with a new value but it does not work (no errors, no replacement of values, nothing happen).
UPDATE Components
SET Unit='kg'
WHERE Unit='КГ'
How can I replace all values "КГ" with "kg" in column Unit?
I thing that your Unit column is NVarChar() data type. Try following query:
UPDATE Components
SET Unit=N'kg'
WHERE Unit=N'КГ'
Another reason: If you have instead of update trigger on Components table and not update this column on it, your update not affected and no raise error too.
I suggest to use Quotename to resolve this, it is used for this type of string.
UPDATE Components
SET Unit=QUOTENAME('kg')
WHERE Unit=QUOTENAME('КГ')
It is simple and direct query which you run, then its ok. Other wise as #Mehdi said, I also fever that statement.
http://www.c-sharpcorner.com/Blogs/7515/quotename-function-in-sql-server.aspx

Resources