function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
adrisseladrissel 

Query returning "line breaks not allowed in string literals" error.

Can anyone tell me what is wrong with the format of this query?:

List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = \''+ String.escapeSingleQuotes(language) +'\' AND KnowledgeArticleId IN :statIds]);

Thank you!
Shyam BhundiaShyam Bhundia
Hi,

What are the potetial values of the variable 'language'? And where does statIds come from?
adrisseladrissel
StatIds come from this:

List<KnowledgeArticleViewStat> statInfo = new List<KnowledgeArticleViewStat>([Select ParentId, NormalizedScore From KnowledgeArticleViewStat where Channel = 'AllChannels' order by NormalizedScore desc]);
        
        for(KnowledgeArticleViewStat statId : statInfo){
        
            statIds.add(statId.ParentId);
        }

That works fine.

Potential variables of language are:

'en_US' , 'es', 'de' ,  'fr' ,  'zh_CN'


Shyam BhundiaShyam Bhundia
Seems like an issue with the placements of " ' ".

Try this query:
List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = '\''+ String.escapeSingleQuotes(language) + '\'' + AND KnowledgeArticleId IN :statIds]);


Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi addrissel,

Use followings:

List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = '\''+ String.escapeSingleQuotes(language) + '\'' + AND KnowledgeArticleId IN :statIds]);
adrisseladrissel
Hello Shyam and Bindhyachal,

Both of your queries are identical, so I put it in my code:

List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = '\''+ String.escapeSingleQuotes(language) + '\'' + AND KnowledgeArticleId IN :statIds]); 
        
        System.Debug('----------------------------------------------------> Here is the value: '+kavs);

Here is the error I received now:

"Compile Error: expecting right square bracket, found '+' at line 38 column 194"

Seems like the number of quotation marks may be off a little.  I will mess around with it myself, but if you have a quick fix that would be great!
Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi adrissel,

Try followings. It can give you results.
 
String languagename = '\''+ String.escapeSingleQuotes(language) + '\'';
List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = :languagename AND KnowledgeArticleId IN :statIds]);
System.Debug('----------------------------------------------------> Here is the value: '+kavs);
adrisseladrissel
I tried something like that and got the same error as when I just tried your version:

Compile Error: Implementation restriction: When querying the KnowledgeArticleVersion object, you must filter using the following syntax: Id = [single ID], Id IN [list of ID's] or Language = [language ISO code]. In addition Language is only permitted in a top-level AND condition. at line 38 column 80

I have no clue as to why this is only failing with the KAV object.  I know for SURE that the value of "language" in this case is "en_us", which is a valud language ISO code.
Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi adrissel,

Your error indicates, need to add id=some id of knowledgeArticleVersion or id IN [list of id of knowledgeArticleVersion]

So, query will be like tis:

String languagename = '\''+ String.escapeSingleQuotes(language) + '\'';
String knowledgeArticleId = [id of the knowledgeArticleversion record];

List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = :languagename AND KnowledgeArticleId IN :statIds AND Id = knowledgeArticleId]);
System.Debug('----------------------------------------------------> Here is the value: '+kavs);

adrisseladrissel

Just to make sure this information is out there, the results of System.Debug calls for "language" and "statIds" produce the following:

language

en_US

statIds

{kA1a0000000d58kCAA, kA1a0000000d58lCAA}

The exact value of "language" has no single quotes in it, does that matter?

adrisseladrissel
Okay, so here is where I am getting the statIds from:

Set<Id> statIds = new Set<Id>();
        
        List<KnowledgeArticleViewStat> statInfo = new List<KnowledgeArticleViewStat>([Select ParentId, NormalizedScore From KnowledgeArticleViewStat where Channel = 'AllChannels' order by NormalizedScore desc]);
        
        for(KnowledgeArticleViewStat statId : statInfo){
        
            statIds.add(statId.ParentId);
        }

The "ParentId" of the KnowledgeArticleViewStat should be a knowledgeArticleId, right?

Then I attempt:

String languagename = '\''+ String.escapeSingleQuotes(language) + '\'';

List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = :languagename AND KnowledgeArticleId IN :statIds]);

System.Debug('----------------------------------------------------> Here is the value: '+kavs);

And get the compile error.

Aren't the "statIds" already KnowledgeArticleIds?

adrisseladrissel
You mean the knowledgeArticeId has the be the Id of the corresponding KnowledgeArticleVersion itself?
Bindhyachal Kumar SinghBindhyachal Kumar Singh
Hi addrissel,

Yes, but when youquery on KAV then need to filter by ID. SO, append id = some id value or id IN: set of ids
adrisseladrissel
Okay, so I now have the following:

To get the statIds:
Set<Id> statIds = new Set<Id>();
        
List<KnowledgeArticleViewStat> statInfo = new List<KnowledgeArticleViewStat>([Select ParentId, NormalizedScore From KnowledgeArticleViewStat where Channel = 'AllChannels' order by NormalizedScore desc]);
        
for(KnowledgeArticleViewStat statId : statInfo){
        
   statIds.add(statId.ParentId);
}

To get the KAV Ids:
Set<Id> kavIds = new Set<Id>();
        
List<KnowledgeArticleVersion> kavInfo = new List<KnowledgeArticleVersion>([SELECT Id FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND KnowledgeArticleId IN :statIds]);
        
for(KnowledgeArticleVersion kavId : kavInfo){
        
   kavIds.add(kavId.Id);
}

Up to here everything is good.  I have two full sets - statIds, and kavIds.

To attempt to get the Article Ids themselves:
Set<Id> artIds = new Set<Id>();
        
String languagename = '\''+ String.escapeSingleQuotes(language) + '\'';
        
List<KnowledgeArticleVersion> kavs = new List<KnowledgeArticleVersion>([SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE PublishStatus = 'online' AND Language = :languagename AND KnowledgeArticleId IN :statIds AND Id IN :kavIds]);

Here is the error I receive:

Error: Compile Error: Implementation restriction: When querying the KnowledgeArticleVersion object, you must filter using the following syntax: Id = [single ID], Id IN [list of ID's] or Language = [language ISO code]. In addition Language is only permitted in a top-level AND condition. at line 51 column 80

As far as I can tell I have included all necessary requirements - I have the language in there, and I now have included the "Id" of a set of KnowledgeArticleVersions.

What am I still missing? 
adrisseladrissel
Let me try it this way.  The following code WORKS:
Set<Id> artIds = new Set<Id>();
        
String queryString = 'SELECT Id, title, UrlName, Summary FROM KnowledgeArticleVersion WHERE (PublishStatus = \'online\') and Language = \''+ String.escapeSingleQuotes(language) +'\' and KnowledgeArticleId in :setIds';
    
for(KnowledgeArticleVersion ka : Database.query(queryString)){
            
   artIds.add(ka.Id);
}
However, I know it is a horrible practice to place a DB query in a for loop, so I am trying to find a way to remove it.  

Does that make finding a solution easier?