query throwing error in web report writer - tsql

I have a query/view that is created to be used in a report. When I run in the SMS and in SSRS it run fine. But when I connect the view to the tool that generates our reports it throws the following error. Incorrect syntax near '.8'. When I contact the support for this product they say it has to do with how we calculate the 8thgradyear . I have placed the code below. Any suggestions.
SELECT
dbo.studemo.suniq,
dbo.studemo.ident,
dbo.studemo.lastname,
dbo.studemo.firstname,
dbo.studemo.emailaddr AS stuemail,
dbo.studemo.birthdate,
dbo.track.schoolc,
dbo.school.schname,
dbo.stustat.graden,
dbo.stustat.edate,
dbo.zstustat.descript AS status,
RTRIM(dbo.facdemo.lastname) + ' ' + dbo.facdemo.firstname AS advisor,
dbo.track.schyear,
SUM(8) - dbo.stustat.graden + dbo.track.schyear AS [8thgradyear],
sf.Email, LOWER(sf.Username) AS [user],
LOWER(RIGHT(SUM(8) - dbo.stustat.graden + dbo.track.schyear, 2) + LEFT(dbo.studemo.firstname, 1) + REPLACE(REPLACE(REPLACE(dbo.studemo.lastname, '-', ''), ' ', ''), '''', '') + RIGHT(dbo.studemo.ident, 3)) AS newuser,
CONVERT(varchar(8), dbo.studemo.birthdate,1) AS password,
'STUDENTS' + '/' + (CASE WHEN track.schoolc IN ('19', '43', '17', '23') THEN 'Middle' ELSE 'Elementary' END) + '/' + dbo.school.schname AS neworg,
sf.OU, sf.LastLoginTime
FROM dbo.studemo INNER JOIN
dbo.stustat ON dbo.studemo.suniq = dbo.stustat.suniq INNER JOIN
dbo.track ON dbo.stustat.trkuniq = dbo.track.trkuniq INNER JOIN
dbo.zstustat ON dbo.stustat.stustatc = dbo.zstustat.stustatc INNER JOIN
dbo.facdemo ON dbo.stustat.funiq = dbo.facdemo.funiq LEFT OUTER JOIN
dbo.vw_google_OU AS sf ON sf.Firstname = dbo.studemo.firstname AND sf.Lastname = dbo.studemo.lastname INNER JOIN
dbo.school ON dbo.school.schoolc = dbo.track.schoolc
WHERE (dbo.stustat.stustatc IN
(SELECT stustatc
FROM dbo.zstustat AS zstustat_1
WHERE (snstatus IN ('A', 'M', 'P')))) AND (dbo.stustat.xdate IS NULL OR
dbo.stustat.xdate < dbo.stustat.edate) AND (dbo.track.schoolc NOT IN ('P34', 'P24', '802', '801'))
GROUP BY dbo.studemo.suniq, dbo.studemo.ident, dbo.studemo.lastname, dbo.studemo.firstname, dbo.studemo.birthdate, RIGHT(dbo.studemo.ident, 3), dbo.track.schoolc,
dbo.stustat.graden, dbo.zstustat.descript, RTRIM(dbo.facdemo.lastname) + ' ' + dbo.facdemo.firstname, dbo.stustat.edate, dbo.studemo.gradyear, dbo.track.schyear,
sf.Email, CONVERT(varchar(8), dbo.studemo.birthdate, 1), sf.Username, dbo.school.schname, sf.OU, dbo.studemo.emailaddr, sf.LastLoginTime

SUM function was introduced in SQL Server 2008 and your tool must be using and older version of SQL Server.

Related

Unable to CAST as TEXT after upgrad to 2.1.212 & 2.1.214

After upgrading from 1.4.200 (provided by spring) to H2 2.1.212 and then 2.1.214, I started seeing this error message when attempting to cast as text:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Precision ("2147483647") must be between "1" and "1000000000" inclusive; SQL statement:
select distinct userpermis0_.user_id as col_0_0_ from markings.user_permissions_map userpermis0_ inner join markings.marking marking1_ on (marking1_.name=userpermis0_.marking_name and marking1_.unique_name=REGEXP_REPLACE(lower(?),'[^a-z0-9]+','-','g')) where (cast(? as varchar(2147483647)) is null or userpermis0_.user_id>?) and (cast(? as varchar(2147483647)) is null or lower(userpermis0_.user_id) like ?) order by userpermis0_.user_id asc limit ? [90150-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:632) ~[h2-2.1.214.jar:2.1.214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) ~[h2-2.1.214.jar:2.1.214]
at org.h2.message.DbException.get(DbException.java:223) ~[h2-2.1.214.jar:2.1.214]
at org.h2.command.Parser.getInvalidPrecisionException(Parser.java:6325) ~[h2-2.1.214.jar:2.1.214]
at org.h2.command.Parser.readIfDataType1(Parser.java:6285) ~[h2-2.1.214.jar:2.1.214]
at org.h2.command.Parser.readIfDataType(Parser.java:6087) ~[h2-2.1.214.jar:2.1.214]
This is the where Query using JPA:
#Query("SELECT DISTINCT u.username"
+ " FROM UserPermissionsMap u"
+ " INNER JOIN Marking m ON m.name = u.markingName AND m.uniqueName = REGEXP_REPLACE(lower(:name), '[^a-z0-9]+', '-', 'g') "
+ " WHERE ( cast(:lastUsernameReturned as text) IS NULL OR u.username > :lastUsernameReturned )"
+ " AND ( cast(:usernameContains as text) IS NULL OR lower(u.username) LIKE %:usernameContains% )")
POM:
...
<h2.version>2.1.214</h2.version>
</properties>
...
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version> << v1.4.200 provided by org.springframework.boot:spring-boot-dependencies:2.5.6
</dependency>
Turns out, I'm able to remove the cast all together, but leave the parenthesis and get the same effect for both H2 & PostgreSQL.
cast(:usernameContains as text) --> (:usernameContains)
They must have fixed the variable replacement when the cast as TEXT was broken.
#Query("SELECT DISTINCT u.username"
+ " FROM UserPermissionsMap u"
+ " INNER JOIN Marking m ON m.name = u.markingName AND m.uniqueName = REGEXP_REPLACE(lower(:name), '[^a-z0-9]+', '-', 'g') "
+ " WHERE ( (:lastUsernameReturned) IS NULL OR u.username > :lastUsernameReturned )"
+ " AND ( (:usernameContains) IS NULL OR lower(u.username) LIKE %:usernameContains% )")

converting sql statement back to lambda expression

I have the query below, and its sql code. It's running really slow, so it was re written in sql, now I'm just not sure how to convert the sql back to a lambda expression.
This is the part of the expression giving me the problems, somewhere in
r.RecordProducts.Any()
records = records
.Include(r => r.Employer)
.Include(r => r.Contractor)
.Include(r => r.RecordProducts)
.ThenInclude(rp => rp.ProductDefendant.Defendant)
.Where(r => EF.Functions.Like(r.Employer.DefendantCode, "%" + input.DefendantCode + "%")
|| EF.Functions.Like(r.Contractor.DefendantCode, "%" + input.DefendantCode + "%")
|| r.RecordProducts.Any(rp => EF.Functions.Like(rp.ProductDefendant.Defendant.DefendantCode, "%" + input.DefendantCode + "%") && rp.IsActive == true));
the any clause does an exist and some funky stuff in the sql where clause below
SELECT [t].[Id], [t].[StartDate], [t].[EndDate], [t].[WitnessName], [t].[SourceCode], [t].[JobsiteName], [t].[ShipName], [t].[EmployerCode]
FROM (
SELECT DISTINCT [r].[RecordID] AS [Id], [r].[StartDate], [r].[EndDate], [r.Witness].[FullName] AS [WitnessName], CASE
WHEN [r].[SourceID] IS NOT NULL
THEN [r.Source].[SourceCode] ELSE N'zzzzz'
END AS [SourceCode], CASE
WHEN [r].[JobsiteID] IS NOT NULL
THEN [r.Jobsite].[JobsiteName] ELSE N'zzzzz'
END AS [JobsiteName], CASE
WHEN [r].[ShipID] IS NOT NULL
THEN [r.Ship].[ShipName] ELSE N'zzzzz'
END AS [ShipName], CASE
WHEN [r].[EmployerID] IS NOT NULL
THEN [r.Employer].[DefendantCode] ELSE N'zzzzz'
END AS [EmployerCode]
FROM [Records] AS [r]
LEFT JOIN [Ships] AS [r.Ship] ON [r].[ShipID] = [r.Ship].[ShipID]
LEFT JOIN [Jobsites] AS [r.Jobsite] ON [r].[JobsiteID] = [r.Jobsite].[JobsiteID]
LEFT JOIN [Sources] AS [r.Source] ON [r].[SourceID] = [r.Source].[SourceID]
LEFT JOIN [Witnesses] AS [r.Witness] ON [r].[WitnessID] = [r.Witness].[WitnessID]
LEFT JOIN [Defendants] AS [r.Contractor] ON [r].[ContractorID] = [r.Contractor].[DefendantID]
LEFT JOIN [Defendants] AS [r.Employer] ON [r].[EmployerID] = [r.Employer].[DefendantID]
WHERE ([r].[IsActive] = 1) AND (([r.Employer].[DefendantCode] LIKE (N'%' + 'cert') + N'%' OR [r.Contractor].[DefendantCode] LIKE (N'%' + 'cert') + N'%') OR EXISTS (
SELECT 1
FROM [Records_Products] AS [rp]
INNER JOIN [Product_Defendant] AS [rp.ProductDefendant] ON [rp].[DefendantProductID] = [rp.ProductDefendant].[DefendantProductID]
INNER JOIN [Defendants] AS [rp.ProductDefendant.Defendant] ON [rp.ProductDefendant].[DefendantID] = [rp.ProductDefendant.Defendant].[DefendantID]
WHERE ([rp.ProductDefendant.Defendant].[DefendantCode] LIKE (N'%' + 'cert') + N'%' AND ([rp].[IsActive] = 1)) AND ([r].[RecordID] = [rp].[RecordID])))
) AS [t]
ORDER BY [t].[SourceCode]
OFFSET 0 ROWS FETCH NEXT 500 ROWS ONLY
Here is the new sql that works better, just not sure how to convert it back to a lambda expression
SELECT [t].[Id]
,[t].[StartDate]
,[t].[EndDate]
,[t].[WitnessName]
,[t].[SourceCode]
,[t].[JobsiteName]
,[t].[ShipName]
,[t].[EmployerCode]
FROM (
SELECT DISTINCT [r].[RecordID] AS [Id]
,[r].[StartDate]
,[r].[EndDate]
,[r.Witness].[FullName] AS [WitnessName]
,CASE
WHEN [r].[SourceID] IS NOT NULL
THEN [r.Source].[SourceCode]
ELSE N'zzzzz'
END AS [SourceCode]
,CASE
WHEN [r].[JobsiteID] IS NOT NULL
THEN [r.Jobsite].[JobsiteName]
ELSE N'zzzzz'
END AS [JobsiteName]
,CASE
WHEN [r].[ShipID] IS NOT NULL
THEN [r.Ship].[ShipName]
ELSE N'zzzzz'
END AS [ShipName]
,CASE
WHEN [r].[EmployerID] IS NOT NULL
THEN [r.Employer].[DefendantCode]
ELSE N'zzzzz'
END AS [EmployerCode]
FROM [Records] AS [r]
LEFT JOIN [Ships] AS [r.Ship] ON [r].[ShipID] = [r.Ship].[ShipID]
LEFT JOIN [Jobsites] AS [r.Jobsite] ON [r].[JobsiteID] = [r.Jobsite].[JobsiteID]
LEFT JOIN [Sources] AS [r.Source] ON [r].[SourceID] = [r.Source].[SourceID]
LEFT JOIN [Witnesses] AS [r.Witness] ON [r].[WitnessID] = [r.Witness].[WitnessID]
LEFT JOIN [Defendants] AS [r.Contractor] ON [r].[ContractorID] = [r.Contractor].[DefendantID]
LEFT JOIN [Defendants] AS [r.Employer] ON [r].[EmployerID] = [r.Employer].[DefendantID]
LEFT JOIN (
SELECT [rp].[RecordID]
FROM [Records_Products] AS [rp]
INNER JOIN [Product_Defendant] AS [rp.ProductDefendant] ON [rp].[DefendantProductID] = [rp.ProductDefendant].[DefendantProductID]
INNER JOIN [Defendants] AS [rp.ProductDefendant.Defendant] ON [rp.ProductDefendant].[DefendantID] = [rp.ProductDefendant.Defendant].[DefendantID]
WHERE (
[rp.ProductDefendant.Defendant].[DefendantCode] LIKE (N'%' + 'cert') + N'%'
AND ([rp].[IsActive] = 1)
)
) AS RecordProduct ON [r].[RecordID] = RecordProduct.[RecordID]
WHERE ([r].[IsActive] = 1)
AND (
(
[r.Employer].[DefendantCode] LIKE (N'%' + 'cert') + N'%'
OR [r.Contractor].[DefendantCode] LIKE (N'%' + 'cert') + N'%'
)
OR RecordProduct.RecordID IS NOT NULL --OR EXISTS ( -- SELECT 1 -- FROM [Records_Products] AS [rp] -- INNER JOIN [Product_Defendant] AS [rp.ProductDefendant] ON [rp].[DefendantProductID] = [rp.ProductDefendant].[DefendantProductID] -- INNER JOIN [Defendants] AS [rp.ProductDefendant.Defendant] ON [rp.ProductDefendant].[DefendantID] = [rp.ProductDefendant.Defendant].[DefendantID] -- WHERE ([rp.ProductDefendant.Defendant].[DefendantCode] LIKE (N'%' + 'cert') + N'%' -- AND ([rp].[IsActive] = 1)) AND ([r].[RecordID] = [rp].[RecordID]) -- ) )) AS [t]ORDER BY [t].[SourceCode]OFFSET 0 ROWS FETCH NEXT 500 ROWS ONLY
)
)
The linq expression you supplied and the SQL generated do not match. For one, the linq expression is performing an Include on the various related tables which would have included all of those entity columns in the top-level SELECT which are not present in your example SQL. I also don't see conditions in the Linq expression for the Take 500 & OrderBy, or IsActive assertion on Record.
To be able to help determine the source of any performance concern we need to see the complete Linq expression and the resulting SQL.
Looking at the basis of the Linq expression you provided:
records = records
.Include(r => r.Employer)
.Include(r => r.Contractor)
.Include(r => r.RecordProducts)
.ThenInclude(rp => rp.ProductDefendant.Defendant)
.Where(r => EF.Functions.Like(r.Employer.DefendantCode, "%" + input.DefendantCode + "%")
|| EF.Functions.Like(r.Contractor.DefendantCode, "%" + input.DefendantCode + "%")
|| r.RecordProducts.Any(rp => EF.Functions.Like(rp.ProductDefendant.Defendant.DefendantCode, "%" + input.DefendantCode + "%") && rp.IsActive == true));
There are a few suggestions I can make:
There is no need for the Functions.Like. You should be able to achieve the same with Contains.
Avoid using Include and instead utilize Select to retrieve the columns from the resulting structure that you actually need. Populate these into ViewModels or consume them in the code. The less data you pull back, the better optimized the SQL can be for indexing, and the less data pulled across the wire. Consuming entities also leads to unexpected lazy-load scenarios as systems mature and someone forgets to Include a new relation.
.
records = records
.Where(r => r.IsActive
&& (r.Employer.DefendantCode.Contains(input.DefendantCode)
|| r.Contractor.DefendantCode.Contains(input.DefendantCode)
|| r.RecordProducts.Any(rp => rp.IsActive
&& rp.ProductDefendant.Defendant.DefendantCode.Contains(input.DefendantCode))
.OrderBy(r => r.SourceCode)
.Select(r => new RecordViewModel
{
// Populate the data you want here.
}).Take(500).ToList();
This also adds the IsActive check, OrderBy, and Take(500) based on your sample SQL.

PGSQL - Joining two tables on complicated condition

I got stuck during database migration on PostgreSQL and need your help.
I have two tables that I need to join: drzewa_mateczne.migracja (data I need to migrate) and ibl_as.t_adres_lesny (dictionary I need to join with migracja).
I need to join them on replace(drzewa_mateczne.migracja.adresy_lesne, ' ', '') = replace(ibl_as.t_adres_lesny.adres, ' ', ''). However my data is not very regular, so I want to join it on first good match with the dictionary.
I've created the following query:
select
count(*)
from
drzewa_mateczne.migracja a
where
length(a.adresy_lesne) > 0
and replace(a.adresy_lesne, ' ', '') = (select substr(replace(al.adres, ' ', ''), 1, length(replace(a.adresy_lesne, ' ', ''))) from ibl_as.t_adres_lesny al limit 1)
The query doesn't return any rows.
It does successfully join empty rows if ran without
length(a.adresy_lesne) > 0
The two following queries return rows (as expected):
select replace(adres, ' ', '')
from ibl_as.t_adres_lesny
where substr(replace(adres, ' ', ''), 1, 16) = '16-15-1-13-180-c'
limit 1
select replace(adresy_lesne, ' ', ''), length(replace(adresy_lesne, ' ', ''))
from drzewa_mateczne.migracja
where replace(adresy_lesne, ' ', '') = '16-15-1-13-180-c'
I'm suspecting that there might be a problem in sub-query inside the 'where' clause in my query. If you guys could help me resolve this issue, or at least point me in the right direction, I'd be very greatful.
Thanks in advance,
Jan
You can largely simplify to:
SELECT count(*)
FROM drzewa_mateczne.migracja a
WHERE a.adresy_lesne <> ''
AND EXISTS (
SELECT 1 FROM ibl_as.t_adres_lesny al
WHERE replace(al.adres, ' ', '')
LIKE (replace(a.adresy_lesne, ' ', '') || '%')
)
a.adresy_lesne <> '' does the same as length(a.adresy_lesne) > 0, just faster.
Replace the correlated subquery with an EXISTS semi-join (to get only one match per row).
Replace the complex string construction with a simple LIKE expression.
More information on pattern matching and index support in these related answers:
PostgreSQL LIKE query performance variations
Difference between LIKE and ~ in Postgres
speeding up wildcard text lookups
What you're basically telling the database to do is to get you the count of rows from drzewa_mateczne.migracja that have a non-empty adresy_lesne field that is a prefix of the adres field of a semi-random ibl_as.t_adres_lesny row...
Lose the "limit 1" in the subquery and substitute the "=" with "in" and see if that is what you wanted...

T-SQL if exists

I am summer intern new to T-SQL and I have to run an sql select statement on various databases. What I would like to do is use 'if exists' to keep an error from occuring because some of the databases on the list to have this statement executed on no longer exist. However, I cannot figure out how to apply it to my statement. Any help would be greatly appreciated. Below is the statment me and another intern wrote:
select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup
from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID
from <db_name>.dbo.matter mat
inner join <db_name>.dbo.usrAccount usr
on usr.NTlogin=mat.matterCreateBy) as mg
inner join <db_name>.dbo.usrGroup grp
on mg.groupID=grp.groupID
order by matterName
the < db_name> is where the passed in parameter that is the name of the database, would go.
You could use sp_MSforeachdb to enumerate all of the databases on the instance.
This would be similar to:
exec sp_MSforeachdb 'select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID from ?.dbo.matter mat inner join ?.dbo.usrAccount usr on usr.NTlogin=mat.matterCreateBy) as mg inner join ?.dbo.usrGroup grp on mg.groupID=grp.groupID order by matterName'
Alternatively, you could use dynamic sql to manufacture a script:
select 'use ' + name + ';' + char(13) + 'select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup' +CHAR(13) + 'from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID' + char(13) + 'from dbo.matter mat' + char(13) + 'inner join dbo.usrAccount usr on usr.NTlogin=mat.matterCreateBy) as mg' + char(13) + 'inner join dbo.usrGroup grp on mg.groupID=grp.groupID' + CHAR(13) + 'order by matterName;'
from master.sys.databases where database_id>4
If you redirect your output to "Results to Text" in SSMS then run the script, you will see a script written that you can then put into a query editor to execute.
I got it to work. I think this is a bit hackey but what I did was catch the exception thrown and just change a label on the page to reflect that the database doesnt exist.
DataAccess dal = new DataAccess();
dal.SelectedConnectionString = "WebServer08";
String exNetName = Request.QueryString["name"];
if (exNetName != null && !exNetName.Equals(""))
{
try
{
gvMatters.DataSource = dal.GetMatters(exNetName);
gvMatters.DataBind();
}
catch (Exception ex)
{
noDB.Text = "This database doesn't exist.";
gvMatters.Visible = false;
}
}
And i just left the SQL statement the way it was rather than try to screw around with it

Sum like operation for strings in t-sql

I already have query to concatenate
DECLARE #ids VARCHAR(8000)
SELECT #ids = COALESCE(#ids + ', ', '') + concatenatedid
FROM #HH
but if I have to do it inline how can I do that? Any help please.
SELECT sum(quantity), COALESCE(#ids + ', ', '') + concatenatedid from #HH
Thanks.
Use the XML PATH trick. You may need a CAST
SELECT
SUBSTRING(
(
SELECT
',' + concatenatedid
FROM
#HH
FOR XML PATH ('')
)
, 2, 7999)
Also:
Join characters using SET BASED APPROACH (Sql Server 2005)
Subquery returned more than 1 value