XML data type method “value” must be a string literal

13,569

Solution 1

You cannot concatenate variables as strings in this way for the value method. You need to use sql:variable("@VariableName").

So your example would be something like this:

Declare @Count Int = 1 
While(@count <= @j) 
Begin 
insert into mytable 
([Word]) 

Select ([XmlColumn].value(N'/word[sql:variable("@Count")]/@Entry)[1]','nvarchar(max)'))
    from OtherTable WHERE ID=2

Solution 2

Thought I'd look for an approach to this that doesn't require the WHILE looping. The main problem is returning an item position along with the node, but I found a workaround in the last answer on this post: http://social.msdn.microsoft.com/Forums/nl/sqlxml/thread/46a7a90d-ebd6-47a9-ac56-c20b72925fb3

So the alternative approach would be:

insert into mytable ([Word]) 
select word from (
    Select 
        words.value('@entry','nvarchar(max)') as word,
        words.value('1+count(for $a in . return $a/../*[. << $a])', 'int') as Pos   
    from
        OtherTable ot
        cross apply ot.XMLColumn.nodes('words/word') x(words)
) sub where Pos <= @j

Basically the inner query returns each word and its position, this can be filtered by the outer query.

For reference my definition of the OtherWords table was:

create table OtherTable (XMLColumn xml)
insert OtherTable (XMLColumn)
select '<words><word entry="Wibble"/><word entry="Hello"/><word entry="World"/></words>'
Share:
13,569

Related videos on Youtube

nona dana
Author by

nona dana

Updated on September 26, 2022

Comments

  • nona dana
    nona dana almost 2 years

    How to change my query so that this error doesn't happen:

    XML data type method “value” must be a string literal

    T-SQL code:

    Declare @Count Int = 1 
    While(@count <= @j) 
    Begin 
    insert into mytable 
    ([Word]) 
    Select ([XmlColumn].value(N'word['+Cast(@Count as nvarchar(2))+']/@Entry','nvarchar(max)')) 
        from OtherTable WHERE ID=2
    
  • HuRN
    HuRN over 8 years
    Do not use the quotes on variable name: sql:variable("@VariableName") -> sql:variable(@VariableName)