In subsonic v2 I can use inline query for full text search in sql server 2008, like this:
DB.Query().ExecuteTypedList<Product>("select * from Product where contains(*, #order)", queryString);
all this works fine.
But now I would like to move on subsonic v3, so I'm trying to get results through SqlQuery, but ExecuteTypedList return an null reference exception:
SubSonic.Query.SqlQuery inlineQuery = new SqlQuery();
inlineQuery.SQLCommand = string.Format("select * from Product where contains(*, '{0}')", queryString);
return inlineQuery.From("Product").ExecuteTypedList<Product>();
PLease prompt me? how I can execute inline query in subsonic v3, to get List<> not a reader
answer is:
return new CodingHorror(string.Format("select * from Product where contains(*, '{0}')", queryString)).ExecuteTypedList<Product>();
Related
I'm trying the standard SELECT ... AS call to rename a column in query output with the Python Salesforce API and it's throwing following error:
... unexpected token: 'AS'", 'errorCode': 'MALFORMED_QUERY'}
So far most native language calls from SOQL have been working in the API and it seems, from here, that SELECT ... AS is valid SOQL.
Query outline:
from simple_salesforce import Salesforce
sf = Salesforce(username=myusername, password=mypassword, security_token=mytoken)
query = "select closedate as Date from opportunity"
query_list = sf.query_all(query)['records']
edit
error remains even after putting the new column name within quotes as advised in above link:
query = "select closedate as \"Date\" from Opportunity"
Thanks
As Terminus mentioned, SOQL field aliasing is not possible in SOQL in most contexts, including yours. The only case in which I have seen aliasing working in SOQL is in aggregate queries. For example, in apex you could write:
AggregateResult myResult = [SELECT count(Id) SpecialName FROM Contact];
system.debug(myResult);
and receive the result:
DEBUG|AggregateResult:{SpecialName=1630}
In python via simple-salesforce it would look like this:
sf.query_all('SELECT count(Id) SpecialName FROM Contact')
with the result:
OrderedDict([('totalSize', 1),
('done', True),
('records',
[OrderedDict([('attributes',
OrderedDict([('type', 'AggregateResult')])),
('SpecialName', 6587)])])])
Please mark as answered if this answer your question.
The syntax seems to be incorrect.
Try query = "select closedate <insert alias> from Opportunity" according to the alias notation documented here : https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_alias.htm
I have been using dynamic query for a project.
Here is an scenario for which I am facing problem.
For a table xyz the column version is stored as varchar (I know it's a poor design, but it's too late to change now) and has values as 9,12.
For the query :
select max(version)
from xyz
where something = 'abc';
I am getting the output as 9 instead of 12.
The dynamic query for the same is:
ClassLoader classLoader = PortletBeanLocatorUtil.getBeanLocator(ClpSerializer.getServletContextName()).getClassLoader();
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(xyz.class, classLoader);
dynamicQuery.setProjection(ProjectionFactoryUtil.max("version"));
dynamicQuery.add(PropertyFactoryUtil.forName("something").eq("abc"));
List<Object> list = xyzLocalServiceUtil.dynamicQuery(dynamicQuery);
The query which is giving the correct value is :
select max(cast(version as signed))
from xyz
where something = 'abc';
Now, I want it to be in the dynamic query, how can I do that?
I am using liferay-6.2-ce
Try using ProjectionFactoryUtil.sqlProjection method.
That method allows using functions that are executed by SQL engine.
For example, I am using following code in order to get the max length of a string column called 'content':
Projection maxSizeProjection = ProjectionFactoryUtil.sqlProjection(
"max(length(content)) as maxSize", new String[] {"maxSize"},
new Type[] {Type.BIG_DECIMAL});
The same thing can be done with dynamic query criterions using RestrictionsFactoryUtil.sqlRestriction in case you want to use a SQL function in a condition.
In your case try following code:
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.Type;
...
Projection maxSizeProjection = ProjectionFactoryUtil.sqlProjection(
"max(cast(version as signed)) as maxVersion",
new String[] {"maxVersion"}, new Type[] {Type.BIG_DECIMAL});
dynamicQuery.setProjection(maxSizeProjection);
Initially I believed these 3 to be doing more or less the same thing with just the notation being different. Until recently, when i noticed that their does exists a big difference between the results of the KeyWordQuery/FullTextQuerySearch and Web service Query.
I used both KeywordQuery and FullText method to search of the the value of a customColumn XYZ with value (ASDSADA-21312ASD-ASDASD):-
When I run this query as:- FullTextSqlQuery:-
FullTextSqlQuery myQuery = new FullTextSqlQuery(site);
{
// Construct query text
String queryText = "Select title, path, author, isdocument from scope() where freetext('ASDSADA-21312ASD-ASDASD') ";
myQuery.QueryText = queryText;
myQuery.ResultTypes = ResultType.RelevantResults;
};
// execute the query and load the results into a datatable
ResultTableCollection queryResults = myQuery.Execute();
ResultTable resultTable = queryResults[ResultType.RelevantResults];
// Load table with results
DataTable queryDataTable = new DataTable();
queryDataTable.Load(resultTable, LoadOption.OverwriteChanges);
I get the following result representing the document.
* Title: TestPDF
* path: http://SharepointServer/Shared Documents/Forms/DispForm.aspx?ID=94
* author: null
* isDocument: false
Do note the Path and isDocument fields of the above result.
Web Service Method
Then I tried a Web Service Query method. I used Sharepoint Search Service Tool available at http://sharepointsearchserv.codeplex.com/ and ran the same query i.e. Select title, path, author, isdocument from scope() where freetext('ASDSADA-21312ASD-ASDASD'). This time I got the following results:-
* Title: TestPDF
* path: http://SharepointServer/Shared Documents/TestPDF.pdf
* author: null
* isDocument: true
Again note the path. While the search results from 2nd method are useful as they provide me the file path exactly, I can't seem to understand why is the method 1 not giving me the same results?
Why is there a discrepancy between the two results?
The first item is a List item, not a document per se. A document library is essentially just another list that is specially made to hold documents in it. The list item likely has some extra metadata not held within the document and so on. The second result is the actual document, so the "isDocument" flag will be up for it.
At least that's my theory.
Ok,
Today I am trying to learn Subsonic. Pretty cool stuff.
I am trying to build some search functionality into my website but am struggling about how I might achieve this in Subsonic.
I have one search field that could contain multiple keywords. I want to return results that match all of the keywords. The target on the search is a single text column.
So far I have this (it runs but never returns results):
return new SubSonic.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(InfopathArchive.XmlDocColumn).Like(keywords)
.ExecuteTypedList<Visit>();
There is a one to one mapping between the Visit table and the InfoPathArchive table. I just want to return the collection of Visits that have the keywords in the related XMLDocColumn.
If I could get that working it would be great. Now the second problem is that if someone searches for 'australia processmodel' then obviously the above code should only return that exact phrase. How can I create a query that splits up my search term so that it must return documents that contain ALL of the individual search terms?
Any help appreciated.
Edit: Ok, so the basic search works, but the multiple keyword search doesnt. I did what Adam suggested but it seems Subsonic only uses one parameter for the query.
Here is the code:
List<string> wordsInQueryList = keywords.Split(' ').ToList();
SqlQuery q = Select.AllColumnsFrom<Visit>()
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(Visit.IsDeletedColumn).IsEqualTo(false);
foreach(string wordInQuery in wordsInQueryList)
{
q = q.And(InfopathArchive.XmlDocColumn).Like("%" + wordInQuery + "%");
}
return q.ExecuteTypedList();
Then if I look at the query that Subsonic generates:
SELECT (bunch of columns)
FROM [dbo].[Visit]
INNER JOIN [dbo].[InfopathArchive] ON [dbo].[Visit].[VisitId] = [dbo].[InfopathArchive].[VisitId]
WHERE [dbo].[Visit].[IsDeleted] = #IsDeleted
AND [dbo].[InfopathArchive].[XmlDoc] LIKE #XmlDoc
AND [dbo].[InfopathArchive].[XmlDoc] LIKE #XmlDoc
So it ends up that only the last keyword is being searched for.
Any ideas?
First question:
return new SubSonic.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where(InfopathArchive.XmlDocColumn).Like("%" + keywords + "%")
.ExecuteTypedList<Visit>();
Second question:
Pass a List of words in your query to a function that builds a SubSonic query as follows
SqlQuery query = DB.Select().From(Visit.Schema)
.InnerJoin(InfopathArchive.VisitIdColumn, Visit.VisitIdColumn)
.Where("1=1");
foreach(string wordInQuery in wordsInQueryList)
{
query = query.And(InfopathArchive.XmlDocColumn).Like("%" + wordInQuery + "%")
}
return query.ExecuteTypedList<Visit>();
Obviously this is untested but it should point you in the right direction.
You can do what Adam is suggesting or with 2.2 you can simply use "Contains()" instead of Like("%...%"). We also support StartsWith and EndsWith() :)
How can I do the following query in subsonic 2.2
select Table1.Id, Table1.Name, Table1.Age from Table1
where Table1.Id =
(
select Max(T.Id) from Table1 T
Where T.Age = 20
)
Can one can provide me with example.
Thanks.
nRk
Subsonic 2.2 can do sub-queries:
As Adam suggested, editted and improved example using In, this works for me:
SubSonic.Select s = new SubSonic.Select(SSDAL.Customer.CustomerIDColumn, SSDAL.Customer.NameColumn);
SubSonic.Aggregate a = new SubSonic.Aggregate(SSDAL.Customer.CustomerIDColumn, SubSonic.AggregateFunction.Max);
SSDAL.CustomerCollection COL = new SSDAL.CustomerCollection();
SubSonic.Select sq = new SubSonic.Select("LastCustomerId");
sq.Aggregates.Add(a);
sq.From(Tables.Customer);
a.Alias = "LastCustomerId";
s.From(Tables.Customer);
s.Where(SSDAL.Customer.CustomerIDColumn).In(sq);
COL = s.ExecuteAsCollection<SSDAL.CustomerCollection>();
;
This code produces the following SQL:
SELECT [dbo].[Customer].[CustomerID], [dbo].[Customer].[Name]
FROM [dbo].[Customer]
WHERE [dbo].[Customer].[CustomerID] IN (SELECT MAX([dbo].[Customer].[CustomerID]) AS 'LastCustomerId'
FROM [dbo].[Customer])
Adam may be onto something but it looks a little ugly. Here is an example that is a bit more readable that returns an IDataReader
new SubSonic.Select(Table1.IdColumn,Table1.NameColumn,Table1.AgeColumn)
.From(Table1.Schema)
.Where(Table1.IdColumn).In(new SubSonic.Select(Aggregate.Max(Table1.IdColumn)).From(Table1.Schema))
.ExecuteReader();
As far as I know there is no support for subqueries in SubSonic. You'll need to put the query in a sproc and use the generated SPs.SprocName() method.
EDIT: I was wrong, see other answer below.