I'm trying to create a stored procedure in sql 2008 to select the id values from some xml like this.
DECLARE #idPolygonXML XML
SET #idPolygonXML =
'<polygons>
<id>35</id>
<id>36</id>
<id>37</id>
<id>38</id>
<id>39</id>
<id>40</id>
</polygons>'
I can get the id for a specific index but I need all of them and I keep getting 'value() requires a singleton'.
Does anyone know how I can get all these values without changing the xml?
Take a look at this: http://msdn.microsoft.com/en-us/library/ms188282.aspx
This isn't tested, but your query would look something like this
SELECT T2.ID.query('.')
CROSS APPLY #idPolygonXML.nodes('/polygons/id') as T2(ID)
Related
I'm trying to figure out how to run an INSERT (i guess update?) query to insert into rows which are nested, but latter rows also have a nested schema in themselves.
For instance i have something like
What would a general template query look like?
I know that for the lines it would look something like
Managed to solve it with:
UPDATE test
SET lines=ARRAY(
SELECT line FROM UNNEST(lines) AS line
UNION ALL
SELECT (
'::someValue::,
ARRAY<STRUCT<STRING,STRING,FLOAT64>>[('someId','someString',1.0)]
)
WHERE id='someId'
Let me simplify with an example. Let's say I have the following query saved on:
C:\sample.sql
grp.id IN
(001 --Bob
,002 --Tom
,003 --Fay
)
Now, that group of IDs could change, but instead of updating those IDs in every query it's related to, I was hoping to just update in sample.sql and the rest of the queries will pull from that SQL file directly.
For example, I have several queries that would have a section like this:
SELECT *
FROM GROUP grp
WHERE grp.DATERANGE >= '2017-12-01 AND grp.DATERANGE <= '2017-12-31
AND -- **this is where I would need to insert that query (ie. C:\sample.sql)**
More explained update:
Issue: I have several reports/queries having the same ID filter (that's the only thing in common between those reports)
What's needed: Instead of updating those IDs every time they change on each report, I was wondering if I can update those IDs in it's own SQL file (like the example above) and have the rest of the queries pull from there.
Note. I can't create a table or database in the used database.
Maybe the bulk insert utility could help. Hold your data in csv files and load them into temp tables at run time. Use these temp tables to drive your query.
CREATE TABLE #CsvData(
Column1 VARCHAR(40),
Column2 VARCHAR(40)
)
GO
BULK
INSERT #CsvData
FROM 'c:\csvtest.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)
GO
--Use #CsvData to drive your query
SELECT *
FROM #CsvData
maybe what you could use is a CTE (Common Table Expression) to pull your IDs using an additional query, specially if you only have read access. It would look something like this:
WITH myIDs AS (select IDs from grp where (conditions to get the IDs))
SELECT *
FROM grp
WHERE grp.DATERANGE BETWEEN '2017-12-01 AND '2017-12-31'
AND IDs in (select * from myIDs)
I've changed the dates syntax to use BETWEEN since it's more practical but only works if you have a SQL Server 2008 or later
Hope this helps!
Cheers!
The only chance to build a query out of text fragments is dynamic SQL:
Try this:
DECLARE #SomeCommand VARCHAR(MAX)='SELECT * FROM sys.objects';
EXEC(#SomeCommand);
Returns a list of all sys.object entries
Now I append a WHERE clause to the string
SET #SomeCommand=#SomeCommand + ' WHERE object_id IN(1,2,3,4,5,6,7,8,9)';
EXEC(#SomeCommand);
And you get a reduced result.
Another option is dynamic IN-list with a CSV paramter.
This is forbidden: DECLARE #idList VARCHAR(100)='1,2,3,4' and use it like IN (#idList).
But this works:
DECLARE #idList VARCHAR(100)='1,2,3,4,5,6,7,8,9';
SELECT sys.objects.*
FROM sys.objects
--use REPLACE to transform the list to <x>1</x><x>2</x>...
OUTER APPLY(SELECT CAST('<x>' + REPLACE(#idList,',','</x><x>') + '</x>' AS XML)) AS A(ListSplitted)
--Now use the XML (the former CSV) within your IN() as set-based filter
WHERE #idList IS NULL OR LEN(#idList)=0 OR object_id IN(SELECT B.v.value('.','int') FROM ListSplitted.nodes('/x') AS B(v));
With a version of SQL Server 2016+ this can be done much easier using STRING_SPLIT().
This approach allows you to pass the id-list as simple text parameter.
I have a something like this in my table column:
{"InputDirection":0,"Mask":"AA","FormatString":null,"AutoCompleteValue":null,
"Filtered":"0123456789","AutoComplete":false,"ReadOnly":true}
What I want to do is to change A to N in "Mask":"AA" and remove "Filtered":"0123456789" if they exist. Mask could be in different forms like A9A, 'AAAA`, etc.
If it was in C# I could do it by myself by parsing it to JSON, etc but I need to do it within SQL.
I've found this article which shows how to parse JSON to Table. This gave me an idea that I can parse each field to temp table and make the changes on that and convert it back to JSON so update the actual field where I take this JSON field from. However, this looks like a cumbersome process for both me and the server.
Any better ideas?
You can use this LINK .
And then use the following code
select * into #demo from
(Select * from parseJSON('{"InputDirection":0,"Mask":"AA","FormatString":null,"AutoCompleteValue":null,
"Filtered":"0123456789","AutoComplete":false,"ReadOnly":true}
')) a
select * from #demo
--- CHANGE THE DATA HERE AS REQUIRED
DECLARE #MyHierarchy JSONHierarchy;
INSERT INTO #myHierarchy
select * from #demo;
-- USE THIS VALUE AND UPDATE YOUR JSON COLUMN
SELECT dbo.ToJSON(#MyHierarchy)
drop table #demo
I may be getting something wrong here but why can’t you simply use REPLACE to update what’s needed and LIKE to identify JSON strings that should be updated?
update table_T
set json_string = REPLACE(json_string, '"Filtered":"0123456789",', '')
where json_string like '%"Mask":"AA"%'
Not sure I understand why do you need to parse it….
So I have a checkboxlist on an ASP.NET form. I need the IDs of the selected checkboxes as part of an IN clause in a stored procedure (SQL Server 2008). Quite straightforward really - let's say the user selects 1, 2, 4, 7, then my procedure would ask for values where TranCode IN (1,2,4,7). Since I can't do a dynamic IN statement, and I don't want to build the query dynamically, I thought XML would be a good choice.
I'm building the XML string thusly in VB.NET - <chargecode><refnum>1</refnum><refnum>2</refnum></chargecode>, etc. TranCode and RefNum represent the same fields, they are just named differently between the transaction table and description table, so I can change refnum to something else in my XML if need be, but I'm definitely going to have to use TranCode for the comparison column.
In my stored procedure I've declared an XML variable called #ChargeCodesXML, which will contain the XML string passed in from VB.NET. Basically all I need to do is pull all the refnum fields out of the XML file for comparison against TranCode. The procedure has several joins, some aggregate functions, group bys, etc., but basically I want something like
SELECT * FROM SomeTable WHERE TranCode IN (SELECT RefNum FROM MyXMLFile)
I've been searching around and have seen many complex XML queries, but nothing as simple as what I need, so I'm kind of overwhelmed by the examples I'm seeing. Can someone please tell me how to modify my proc for this very simple comparison?
Thanks!
Mike
Something like this should sort your problem:
SELECT * FROM SomeTable WHERE TranCode IN (
SELECT
ChargeCode.RefNum.value('.', 'INT')
FROM
#ChargeCodesXML.nodes('/chargecode/refnum') AS ChargeCode(RefNum)
)
The key part to this query is that you use the nodes method to shred the XML. If you're going to be spending any significant amount of time working with XML in SQL Server 2008, I suggest you do some reading up on this.
SELECT *
FROM SomeTable
WHERE TranCode IN (
SELECT T.N.value('(./text())[1]', 'int')
FROM #ChargeCodesXML.nodes('/chargecode/refnum') AS T(N)
)
Actually both tables are the same, and I just need to merge data. Problem is that one column is defined with XML shema, which is same in both tables, and for my query I am getting this error from sql server studio:
"Implicit conversion between XML types constrained by different XML schema collections is not allowed. Use the CONVERT function to run this query."
Help me writedown this query.
I have something like this:
INSERT INTO table1
SELECT * FROM table2
WHERE id NOT IN (select id from table1);
Without more info on your table structure and the xml schemas I'm not sure how much assistance I can be. That said there's an article that discusses this exact problem here
http://sqlblogcasts.com/blogs/martinbell/archive/2010/11/08/Using-XML-Schemas.aspx
And his example of using the convert statement to overcome exactly this problem is as follows.
INSERT INTO [dbo].[Test_ProductModel_Content]( [CatalogDescription] )
SELECT CONVERT(XML, [CatalogDescription] )
FROM AdventureWorks2008.Production.ProductModel
WHERE [CatalogDescription] IS NOT NULL ;
GO
Hope that helps, if not post more information and I'm sure someone can help you out.