Convert SQL to FetchXML error? - sql

Just a quick one trying to convert the below to Fetch XML, however have the error below.
Error: Error occurred when parsing the SQL script: Unsupported statement type: DECLARE
DECLARE
#OrganisationId uniqueidentifier
SELECT
cil.mm_topprioritystatus,
cil.mm_achievedcatalogproductName,
cil.mm_achievedcatalogproductstatus,
ci.mm_key
FROM
mm_catalogitemtorganisationlinker cil
INNER JOIN
mm_catalogitem ci on
ci.mm_catalogitemId = cil.mm_catalogitem
where
mm_organisation = #OrganisationId
and ci.mm_key in (
'LEVEL1',
'LEVEL2',
'LEVEL3',
'LEVEL4'
)
Please advise for the fetchXML version of above.

This is one possible solution:
<fetch>
<entity name='mm_catalogitemtorganisationlinker' >
<attribute name='mm_topprioritystatus' />
<attribute name='mm_achievedcatalogproductName' />
<attribute name='mm_achievedcatalogproductstatus' />
<filter>
<condition attribute='mm_organisation' operator='eq' value='{organizationid}' />
</filter>
<link-entity name='mm_catalogitem' from='mm_catalogitemid' to='mm_catalogitem' link-type='inner' alias='ci' >
<attribute name='mm_key' />
<filter>
<condition attribute='mm_key' operator='in' >
<value>LEVEL1</value>
<value>LEVEL2</value>
<value>LEVEL3</value>
<value>LEVEL4</value>
</condition>
</filter>
</link-entity>
</entity>
</fetch>
Of course you have to replace the {organizationid} placeholder by code.

Related

How can I highlight syntax in Microsoft OneNote 2013?

I want to highlight syntax for my programming language of choice (proprietary) in Microsoft OneNote 2013 with a macro or script. I found a free Macro creator for MS OneNote '13 that allows creation of custom macros called "OneTastic". I created a macro that is given two arrays with lists of predefined words associated with different colors to give each list (ex: List 1 words = blue, list 2 words = orange, etc.)
API: https://www.omeratay.com/onetastic/docs/
Problem: The search logic is finding words inside of bigger words, like "IN" inside of the word "domain" (domaIN). My code is below:
<?xml version="1.0" encoding="utf-16"?>
<Macro name="CCL TEST 3" category="Color" description="" version="10">
<ModifyVar name="KEYWORDS1" op="set">
<Function name="String_Split">
<Param name="string" value="drop create program go %i declare call set end END execute else elseif protect constant curqual of subroutine to noconstant record free range in is protect define macro endmacro" />
<Param name="delimiter" value=" " />
</Function>
</ModifyVar>
<ModifyVar name="counter" op="set" value="0" />
<WhileVar name="counter" op="lt">
<Function name="Array_Length">
<Param name="array" var="KEYWORDS1" />
</Function>
<IsRootOp />
<ModifyVar name="keyword" op="set" var="KEYWORDS1">
<RightIndex var="counter" />
</ModifyVar>
<For each="Text">
<That hasProp="value" op="eq" var="keyword" />
<ModifyProp name="fontColor" op="set" value="blue" />
</For>
<ModifyVar name="counter" op="add" value="1" />
</WhileVar>
<ModifyVar name="KEYWORDS2" op="set">
<Function name="String_Split">
<Param name="string" value="datetimefind datetimediff cnvtdatetime cnvtalias format build concat findfile error alterlist alter initrec cnvtdate esmError echo max min avg sum count uar_get_code_meaning mod substring size trim hour day isnumeric expand locateval cnvtstring fillstring btestfindstring logical uar_get_code_display uar_get_meaning_by_codeset UAR_GET_CODE_BY sqltype cnvtreal echorecord cnvtupper cnvtlower cnvtdatetimeutc abs datetimediff year julian btest decode evaluate findstring asis replace validate nullterm parser value uar_timer_create uar_CreatePropList uar_SetPropString uar_CloseHandle uar_Timer_Destroy uar_Timer_Stop build2 patstring piece cnvtalphanum timestampdiff" />
<Param name="delimiter" value=" " />
</Function>
</ModifyVar>
<ModifyVar name="counter2" op="set" value="0" />
<WhileVar name="counter2" op="lt">
<Function name="Array_Length">
<Param name="array" var="KEYWORDS2" />
</Function>
<IsRootOp />
<ModifyVar name="keyword" op="set" var="KEYWORDS2">
<RightIndex var="counter2" />
</ModifyVar>
<For each="Text">
<That hasProp="value" op="eq" var="keyword" />
<ModifyProp name="fontColor" op="set" value="orange" />
</For>
<ModifyVar name="counter2" op="add" value="1" />
</WhileVar>
</Macro>
There is no such inbuilt feature available in OneNote but you can do it.
Use Visual Studio Code, it's free. Turn on right text copy/pasting. Write your code in in VS code. Copy it. It'll paste exactly as you see. Colors and all.
While this does not use VBA, I use and love the add-in NoteHightlight2016
If you don't find a language you can go through and add your own. I've added the Excel Formula keywords to the languages supported and I believe it is a bit easier than creating in OneTastic, which I also use and love.

Parse out XML Value in SQL Server

I have the following XML contained in a column XML_TRANSACTION in a table TRANSACTION in SQL Server. I am trying to parse out the information inside the From and To tags into separate columns:
<Transaction Id="1234" Timestamp="2012-04-28T05:02:20" Version="TransactionVersion2" SenderId="abcd" SenderLocId="vxyz">
<Instance Name="Home" />
<Messages>
<Message Id="0" Timestamp="2014-04-28T01:00:46">
<MessageRequest Name="Movement" Xsd="Movement.xsd" Version="5">
<Body>
<Parts>
<Part PartNumber="11111" Qty="1" PersonUniqueId="A1B2C3" />
</Parts>
<Order Number="13579" Uid="01" />
<Ship Number="1ZW23" Type="Out" />
<From VendorId="XY1X2" VendorLocId="XY1X2" VendorName="Vendor_Extra" VendorStockRoom="OPEN" CountryCode="US" />
<To VendorId="XY1X2" VendorLocId="XY1X2" VendorName="Vendor_Extra" VendorStockRoom="CLOSED" CountryCode="US" />
</Body>
</MessageRequest>
</Message>
</Messages>
</Transaction>
Desired results:
From_VendorID || From_VendorLocID || From_VendorName || To_VendorID || To_VendorLocID
--------------++------------------++--------------------------------------------------
XY1X2 || XY1X2 || Vendor_Extra || XY1X2 || XY1X2
etc.
I have made several attempts, but have been unsuccessful. Any assistance would be greatly appreciated!
This should get you started:
SELECT
t.[XML_TRANSACTION].value('(//From/#VendorId)[1]','varchar(20)') as From_VendorID
,t.[XML_TRANSACTION].value('(//From/#VendorLocId)[1]','varchar(20)') as From_VendorLocID
,t.[XML_TRANSACTION].value('(//To/#VendorLocId)[1]','varchar(20)') as To_VendorLocID
,t.[XML_TRANSACTION].value('(//To/#VendorLocId)[1]','varchar(20)') as To_VendorLocID
FROM [CD].[TEST] AS t

The target of 'replace' must be at most one node

I'm trying to modify an XML value but keep getting the message
The target of the replace must be at most one node, found attribute(prefType, xdt:untypedAtomic)
First here is my XML
<preferences>
<categories>
<category id="1" prefType="2">
<subcat id="1" prefType="2" />
<subcat id="2" prefType="2" />
<subcat id="3" prefType="2" />
<subcat id="77" prefType="2" />
</category>
<category id="2" prefType="2">
<subcat id="9" prefType="2" />
<subcat id="10" prefType="2" />
<subcat id="11" prefType="2" />
<subcat id="12" prefType="2" />
<subcat id="13" prefType="2" />
<subcat id="14" prefType="2" />
<subcat id="17" prefType="2" />
<subcat id="78" prefType="2" />
<subcat id="101" prefType="2" />
</category>
<category id="3" prefType="2">
<subcat id="18" prefType="2" />
<subcat id="19" prefType="2" />
<subcat id="20" prefType="2" />
</category>
</categories>
</preferences>
And my code
declare #XMLinput as XML;
declare #custXML as XML;
declare #subcatid as nvarchar(3);
declare #interest as nvarchar(8);
declare #newValue as varchar(1);
declare #cnt as int;
set #XMLinput = '<preferences><categoryId>73</categoryId><interestLevel>POSITIVE</interestLevel></preferences>';
-- get the subcatid and interest level
SET #subcatid = #XMLinput.value('(//preferences/categoryId)[1]','nvarchar(3)');
SET #interest = #XMLinput.value('(//preferences/interestLevel)[1]','nvarchar(20)');
SET #newValue =
CASE #interest
WHEN 'POSITIVE' THEN '1'
WHEN 'NEGATIVE' THEN '3'
ELSE '2'
END;
set #custXML = (select Preferences from Customer_Preferences where custID=11584);
select #custXML.exist('//preferences/categories/category/subcat[#id=sql:variable("#subcatid")]');
if (##ROWCOUNT > 0)
BEGIN TRY
BEGIN TRAN;
set #cnt = CAST(CAST(#custXML.query('count(//preferences/categories/category/subcat[#id=(sql:variable("#subcatid"))])') AS VARCHAR) AS INT);
-- replace the value
UPDATE Customer_Preferences
SET preferences.modify('
replace value of
(//*/subcat[#id=sql:variable("#subcatid")]/#prefType[1])
with sql:variable("#newValue")
')
where CustID = 11584;
COMMIT TRAN;
END TRY
BEGIN CATCH
select XACT_STATE() as 'XACT_STATE', ##TRANCOUNT as '##TRANCOUNT';
if ##TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH
select preferences from Customer_Preferences where custid=11584
SELECT XACT_STATE() as 'XACT_STATE', ##TRANCOUNT AS '##TRANCOUNT'
I've tried removing the sql variables and replacing them with fixed values but still get the same issue. I've also tried removing all the XML subcats except for one and the same error occurs.
After 3 hours of working through this and getting no where, I'd really appreciate your help.
Just as further reference (although you solved your problem already on your own) for others with similar problems: Here is what actually went wrong: The error message already indicates that the replace target can be at most one value (meaning you can replace only one value at a time).
However, (//*/subcat[#id=sql:variable("#subcatid")]/#prefType[1]) yields a sequence of results What is means literally is to take each subcat element and select the first attribute with the name prefType. This actually does not make much sense as an XML element can not have multiple attributes with the same name, so the query would be the same without the [1] predicate.
What you probably wanted to write is: Give me each prefType attribute of each subcat element and return only the first one of the whole result set. That is exactly what your working query is doing: (//*/subcat[#id=sql:variable("#subcatid")]/#prefType)[1]

update xml attribute in xml returns error SQL

Im trying to update an attribute of an xml in SQL.
My XML is stored on a variable #tmpRespXML:
<Responses>
<x id="3" name="Good" val="0" seq="0" createsr="0" />
<x id="4" name="Fair" val="0" seq="0" createsr="0" />
<x id="5" name="Needs Repair" val="1" seq="0" createsr="0" />
<x id="6" name="Not Inspected" val="1" seq="0" createsr="0" />
<x id="7" name="N/A" val="1" seq="0" createsr="0" />
</Responses>
So what I did is to put the xml in a temp table.
DECLARE #tmpRespTBL TABLE(Responses XML)
INSERT #tmpRespTBL VALUES(#tmpRespXML)
and then update the table. I'm trying to set the attribute #createsr to 1 where my attribute #id is equal to #items
UPDATE #tmpRespTBL
SET Responses.modify('replace value of(/Responses/x[#id=("'+#items+'")]/#createsr)[1] with "1"')
This returns the ff error:
Msg 8172, Level 16, State 1, Line 30 The argument 1 of the xml data
type method "modify" must be a string literal.
What am I missing here?
Try with
SET Responses.modify('replace value of(/Responses/x[#id=("''+#items+''")]/#createsr)[1] with "1"')
That should fix your issue. What I did here is escape the '

StoredProcedure returning multiple resultset Sql To Linq using designer

I want to get multiple resultsets from a storedProc using sql to linq. I was not able to generate it from designer so I wrote below code in designer.cs file. But whenever I add something to designer, it refreshes the designer with the markup in .dbml file and hence it removes the below code every time I add something. I have to copy it every time. If I can get corresponding dbml markup for this, it would be great.
[Function(Name = "dbo.GetAllModulesAndOptions")]
[ResultType(typeof(Module))]
[ResultType(typeof(ModuleOption))]
public IMultipleResults GetAllModules()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
return ((IMultipleResults)(result.ReturnValue));
}
I've already defined Module and ModuleOption as tables.
Now when I add below markup in .dbml file it complains
DBML1114: The Name attribute 'Module' of the Type element is already used by another type.
<Function Name="dbo.GetAllModulesAndOptions" Method="GetAllModules">
<ElementType Name="Module">
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<Column Name="ModuleName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="Description" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="SalesDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="ParentModuleId" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
<ElementType Name="ModuleOption">
<Column Name="ModuleOptionId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ModuleOptionName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="ModuleOptionDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="DefaultPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt" CanBeNull="true" />
<Column Name="InUse" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
</Function>
I'm using Visual Studio 2008 SP1
Add the method to the partial class for the data context.
You achieve this by adding a file with the same name as the data context alongside the dbml file, and use the class declaration:
public partial class YourDataContext
{
[Function(Name = "dbo.GetAllModulesAndOptions")]
[ResultType(typeof(Module))]
[ResultType(typeof(ModuleOption))]
public IMultipleResults GetAllModules()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo (MethodInfo.GetCurrentMethod())));
return ((IMultipleResults)(result.ReturnValue));
}
}
I'm replying my own answer.
One cannot use the already defined type for result set of stored procedure. So I had to change the name of ElementType to ModuleResult and ModuleOptionResult.
<Function Name="dbo.GetAllModulesAndOptions" Method="GetAllModules">
<ElementType Name="ModuleResult">
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<Column Name="ModuleName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="Description" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="SalesDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="ParentModuleId" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
<ElementType Name="ModuleOptionResult">
<Column Name="ModuleOptionId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ModuleOptionName" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="ModuleOptionDesc" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="DefaultPrice" Type="System.Decimal" DbType="Money" CanBeNull="true" />
<Column Name="ModuleId" Type="System.Int64" DbType="BigInt" CanBeNull="true" />
<Column Name="InUse" Type="System.Int32" DbType="Int" CanBeNull="true" />
</ElementType>
</Function>
Here are the steps which I took to solve the above problem.
Delete the .designer.cs file
Add above markup to the .dbml file
Exclude .dbml and .dbml.layout file
Include .dbml and .dbml.layout file (this will generate .designer.cs file again but will not include it in the project).
Include .designer file in project.
Get the list of Module type and ModuleOption type as below.
var modules = from row in results.GetResult<ModuleResult>().ToList()
select new Module
{
ModuleId = row.ModuleId,
ModuleName = row.ModuleName,
Description = row.Description,
SalesDesc = row.SalesDesc,
ParentModuleId = row.ParentModuleId
};
var moduleOptions = from row in results.GetResult<ModuleOptionResult>().ToList()
select new ModuleOption
{
ModuleOptionId = row.ModuleOptionId,
ModuleOptionName = row.ModuleOptionName,
ModuleOptionDesc = row.ModuleOptionDesc,
DefaultPrice = row.DefaultPrice,
ModuleId = row.ModuleId,
InUse = row.InUse
};
UPDATE
Still a better way.
Right click the dbml file in solution explorer and select open with. Choose XML Editor and when you save the file within visual studio it automatically generates the designer.cs file.