I cannot get this TRIM code to work
SELECT
dbo.COL_V_Cost_GEMS_Detail.TNG_SYS_NR AS [EHP Code],
dbo.COL_TBL_VCOURSE.TNG_NA AS [Course Title],
LTRIM(RTRIM(FCT_TYP_CD)& ') AND (' & LTRIM(RTRIM(DEP_TYP_ID) & ')' AS [Course Owner]
You are missing two closing parentheses...and I am not sure an ampersand works as a string concatenation operator. Try '+'
SELECT dbo.COL_V_Cost_GEMS_Detail.TNG_SYS_NR AS [EHP Code],
dbo.COL_TBL_VCOURSE.TNG_NA AS [Course Title],
LTRIM(RTRIM(FCT_TYP_CD)) + ') AND (' + LTRIM(RTRIM(DEP_TYP_ID)) + ')' AS [Course Owner]
TRIM all SPACE's TAB's and ENTER's:
DECLARE #Str VARCHAR(MAX) = '
[ Foo ]
'
DECLARE #NewStr VARCHAR(MAX) = ''
DECLARE #WhiteChars VARCHAR(4) =
CHAR(13) + CHAR(10) -- ENTER
+ CHAR(9) -- TAB
+ ' ' -- SPACE
;WITH Split(Chr, Pos) AS (
SELECT
SUBSTRING(#Str, 1, 1) AS Chr
, 1 AS Pos
UNION ALL
SELECT
SUBSTRING(#Str, Pos, 1) AS Chr
, Pos + 1 AS Pos
FROM Split
WHERE Pos <= LEN(#Str)
)
SELECT #NewStr = #NewStr + Chr
FROM Split
WHERE
Pos >= (
SELECT MIN(Pos)
FROM Split
WHERE CHARINDEX(Chr, #WhiteChars) = 0
)
AND Pos <= (
SELECT MAX(Pos)
FROM Split
WHERE CHARINDEX(Chr, #WhiteChars) = 0
)
SELECT '"' + #NewStr + '"'
As Function
CREATE FUNCTION StrTrim(#Str VARCHAR(MAX)) RETURNS VARCHAR(MAX) BEGIN
DECLARE #NewStr VARCHAR(MAX) = NULL
IF (#Str IS NOT NULL) BEGIN
SET #NewStr = ''
DECLARE #WhiteChars VARCHAR(4) =
CHAR(13) + CHAR(10) -- ENTER
+ CHAR(9) -- TAB
+ ' ' -- SPACE
IF (#Str LIKE ('%[' + #WhiteChars + ']%')) BEGIN
;WITH Split(Chr, Pos) AS (
SELECT
SUBSTRING(#Str, 1, 1) AS Chr
, 1 AS Pos
UNION ALL
SELECT
SUBSTRING(#Str, Pos, 1) AS Chr
, Pos + 1 AS Pos
FROM Split
WHERE Pos <= LEN(#Str)
)
SELECT #NewStr = #NewStr + Chr
FROM Split
WHERE
Pos >= (
SELECT MIN(Pos)
FROM Split
WHERE CHARINDEX(Chr, #WhiteChars) = 0
)
AND Pos <= (
SELECT MAX(Pos)
FROM Split
WHERE CHARINDEX(Chr, #WhiteChars) = 0
)
END
END
RETURN #NewStr
END
Example
-- Test
DECLARE #Str VARCHAR(MAX) = '
[ Foo ]
'
SELECT 'Str', '"' + dbo.StrTrim(#Str) + '"'
UNION SELECT 'EMPTY', '"' + dbo.StrTrim('') + '"'
UNION SELECT 'EMTPY', '"' + dbo.StrTrim(' ') + '"'
UNION SELECT 'NULL', '"' + dbo.StrTrim(NULL) + '"'
Result
+-------+----------------+
| Test | Result |
+-------+----------------+
| EMPTY | "" |
| EMTPY | "" |
| NULL | NULL |
| Str | "[ Foo ]" |
+-------+----------------+
LTRIM(RTRIM(FCT_TYP_CD)) & ') AND (' & LTRIM(RTRIM(DEP_TYP_ID)) & ')'
I think you're missing a ) on both of the trims. Some SQL versions support just TRIM which does both L and R trims...
Example:
DECLARE #Str NVARCHAR(MAX) = N'
foo bar
Foo Bar
'
PRINT '[' + #Str + ']'
DECLARE #StrPrv NVARCHAR(MAX) = N''
WHILE ((#StrPrv <> #Str) AND (#Str IS NOT NULL)) BEGIN
SET #StrPrv = #Str
-- Beginning
IF EXISTS (SELECT 1 WHERE #Str LIKE '[' + CHAR(13) + CHAR(10) + CHAR(9) + ']%')
SET #Str = LTRIM(RIGHT(#Str, LEN(#Str) - 1))
-- Ending
IF EXISTS (SELECT 1 WHERE #Str LIKE '%[' + CHAR(13) + CHAR(10) + CHAR(9) + ']')
SET #Str = RTRIM(LEFT(#Str, LEN(#Str) - 1))
END
PRINT '[' + #Str + ']'
Result
[
foo bar
Foo Bar
]
[foo bar
Foo Bar]
Using fnTrim
Source: https://github.com/reduardo7/fnTrim
SELECT dbo.fnTrim(colName)
Related
I work on SQL server 2012 I face issue : there are generated strange text when select from #Body
as ">"
How to remove that and why is generated ?
this signature as > do problem for me when do select data
select #Body from table
it give me error incorrect syntax near ';'
sample data :
create table #FinalTable
(
PART_ID nvarchar(50) ,
CompanyName nvarchar(50),
PartNumber nvarchar(50),
DKFeatureName nvarchar(100),
value nvarchar(50),
StatusId int,
DisplayOrder int,
splitFlag bit
)
insert into #FinalTable(
PART_ID ,
CompanyName ,
PartNumber ,
DKFeatureName ,
value ,
StatusId ,
DisplayOrder ,
splitFlag)
values
('1222','Honda','silicon','package','15.50Am',2,5,0),
('1900','MERCEIS','GLASS','family','90.00Am',2,2,1),--have column per Unit on #Header because FlagAllow=1
('5000','TOYOTA','alominia','source','70.20kg',2,1,0),
('8000','MACDA','motor','parametric','50.40kg',2,3,1),--have column per Unit on #Header because FlagAllow=1
('8900','JEB','mirror','noparametric','75.35kg',2,4,0)
DECLARE #Body NVARCHAR(MAX)
SELECT
#Body = STUFF(
(
SELECT ', ' + case when A.splitFlag = 1 and a.value<> '-' and (a.Value is not null) then 'LEFT(' + QUOTENAME (A.DKFeatureName) + ',PATINDEX(''%[^0-9.]%'',' + QUOTENAME (A.DKFeatureName) + '+ ' + ''' ''' + ')-1) as ['+A.DKFeatureName+'],(CASE WHEN PATINDEX(''%[^0-9.]%'', '+ A.DKFeatureName + ') > 0 THEN RIGHT('+ QUOTENAME (A.DKFeatureName) +',LEN('+ QUOTENAME (A.DKFeatureName) +') - PATINDEX(''%[^0-9.]%'','+ QUOTENAME (A.DKFeatureName) +')+1)) ELSE NULL END) as ['+A.DKFeatureName +'Units'+']' else quotename(A.DKFeatureName) end
FROM #FinalTable A
where StatusId=2
ORDER BY A.DisplayOrder
FOR XML PATH ('')
),1,2,''
)
print #Body
string generated as below :
[Series], [Cable Type], LEFT([Impedance],PATINDEX('%[^0-9.]%',[Impedance]+ ' ')-1) as [Impedance],(CASE WHEN PATINDEX('%[^0-9.]%', Impedance) > 0 THEN RIGHT([Impedance],LEN([Impedance]) - PATINDEX('%[^0-9.]%',[Impedance])+1)) ELSE NULL END) as [ImpedanceUnits], LEFT([Frequency - Max],PATINDEX('%[^0-9.]%',[Frequency - Max]+ ' ')-1) as [Frequency - Max],(CASE WHEN PATINDEX('%[^0-9.]%', Frequency - Max) > 0 THEN RIGHT([Frequency - Max],LEN([Frequency - Max]) - PATINDEX('%[^0-9.]%',[Frequency - Max])+1)) ELSE NULL END) as [Frequency - MaxUnits], [Color]
Expected result gt must be > and remove semi colon and &
[Series], [Cable Type], LEFT([Impedance],PATINDEX('%[^0-9.]%',[Impedance]+ ' ')-1) as [Impedance],(CASE WHEN PATINDEX('%[^0-9.]%', Impedance) > 0 THEN RIGHT([Impedance],LEN([Impedance]) - PATINDEX('%[^0-9.]%',[Impedance])+1)) ELSE NULL END) as [ImpedanceUnits], LEFT([Frequency - Max],PATINDEX('%[^0-9.]%',[Frequency - Max]+ ' ')-1) as [Frequency - Max],(CASE WHEN PATINDEX('%[^0-9.]%', Frequency - Max) > 0 THEN RIGHT([Frequency - Max],LEN([Frequency - Max]) - PATINDEX('%[^0-9.]%',[Frequency - Max])+1)) ELSE NULL END) as [Frequency - MaxUnits], [Color]
I need display gt& as > 0
You need to use the TYPE key word to enforce the characters to be retained, and then extract the value of your text in the generated XML instead using value:
DECLARE #Body nvarchar(MAX);
SELECT #Body = STUFF((SELECT ', ' + CASE
WHEN A.splitFlag = 1
AND A.value <> '-'
AND (A.Value IS NOT NULL) THEN 'LEFT(' + QUOTENAME(A.DKFeatureName) + ',PATINDEX(''%[^0-9.]%'',' + QUOTENAME(A.DKFeatureName) + '+ ' + ''' ''' + ')-1) as [' + A.DKFeatureName + '],(CASE WHEN PATINDEX(''%[^0-9.]%'', ' + A.DKFeatureName + ') > 0 THEN RIGHT(' + QUOTENAME(A.DKFeatureName) + ',LEN(' + QUOTENAME(A.DKFeatureName) + ') - PATINDEX(''%[^0-9.]%'',' + QUOTENAME(A.DKFeatureName) + ')+1)) ELSE NULL END) as [' + A.DKFeatureName + 'Units' + ']'
ELSE QUOTENAME(A.DKFeatureName)
END
FROM #FinalTable A
WHERE StatusId = 2
ORDER BY A.DisplayOrder
FOR XML PATH(''),TYPE).value('(./text())[1]','nvarchar(MAX)'),1,2,'');
PRINT #Body;
I am using the following dynamic query, but see that the performance is slow. I am not a big fan of dynamic SQL, and am looking for, if possible, a good clean and fast SQL alternative for the following. Thanks a million ton in advance! Here are some details:
In the following code, the final table missingfields_xxxx lists out the rows where we have a missing rule field.
table_name has the column rule that holds the column name of the table trans_modelname (this table can be found in the dynamic part of the sql)
DECLARE #rule NVARCHAR(MAX)
DECLARE #PeriodNumber INT = 1
DECLARE #SelectList NVARCHAR(MAX)
DECLARE #WhereList NVARCHAR(MAX)
DECLARE #SQL NVARCHAR(MAX)
DECLARE #ModelName as NVARCHAR(MAX) = 'modelname'
--DECLARE #MaxPeriods INT = 8
DECLARE #MaxPeriods INT
SELECT #MaxPeriods = count (*)
FROM
(
SELECT [rule]
FROM table_name
WHERE ModelName = #ModelName) ab
DECLARE db_cursor3 CURSOR FOR
SELECT * FROM
(
SELECT [rule]
FROM table_name
WHERE ModelName = #ModelName) cd
OPEN db_cursor3
FETCH NEXT FROM db_cursor3 INTO #rule
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN
SELECT #SelectList = COALESCE(#SelectList + ', ', '') + '' + #rule + ' AS [GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + ']'
SELECT #SelectList as 'Selectlist'
IF #PeriodNumber < #MaxPeriods
BEGIN
SELECT #WhereList = COALESCE(#WhereList, '') + '(isnull([GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + '],'''') = '''' ) OR '
SELECT #WhereList as 'Wherelist where periodnumber < maxperiods'
END
ELSE IF #PeriodNumber = #MaxPeriods
BEGIN
SELECT #WhereList = COALESCE(#WhereList, '') + '(isnull([GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + '], '''') = '''' )'
SELECT #WhereList as 'Wherelist where periodnumber = maxperiods'
END
SET #PeriodNumber = #PeriodNumber + 1
END
FETCH NEXT FROM db_cursor3 INTO #rule
END
CLOSE db_cursor3
DEALLOCATE db_cursor3
-- build dynamic query
SET #SQL =
'SELECT * into missingfields_' + #ModelName + ' from trans_' + #ModelName + '
WHERE id in
(
SELECT id from
(
SELECT id, ' + #SelectList + '
FROM trans_' + #ModelName + ')A
WHERE ' + #WhereList + '
);
SELECT * from missingfields_' + #ModelName
PRINT #SQL
print 'missingfields_' + #ModelName
EXEC sp_executesql #SQL
I'm stuck in the utf-8 format. I used CAST or CONVERT USING UTF-8. Even I set character N in front of query string but it's still not working.
My stored procedure:
ALTER PROCEDURE [dbo].[SPC_SP_HSDXTChinh_BangSo4_Fake]
#idDuAn NUMERIC(18, 0),
#idGoiThau NUMERIC(18, 0),
#idDonVi INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #resultString NVARCHAR(MAX);
DECLARE #queryString NVARCHAR(MAX);
DECLARE #Str_TinhHopLe NVARCHAR(255), #Str_DanhGia NVARCHAR(255), #Str_XepHang NVARCHAR(255);
SET #Str_TinhHopLe = 'N''Kết quả đánh giá tính hợp lệ của HSĐXTC''';
SET #Str_DanhGia = 'N''Giá đánh giá''';
SET #Str_XepHang = 'N''Xếp hạng các HSDT''';
SELECT #resultString = COALESCE(#resultString + ',', '') + RES.TenNhaThau
FROM (
SELECT '[' + TenNhaThau + ']' AS TenNhaThau
FROM [SPC_fn_HSDXTChinh_NhaThau_CoTinhHopLe] (#idDuAn, #idGoiThau, #idDonVi)
) RES
--PRINT #resultString
PRINT #Str_TinhHopLe;
SET #queryString = '
SELECT *
FROM (
SELECT 1 AS STT,' + #Str_TinhHopLe + ' AS NoiDung,
CAST(RES.TenNhaThau AS NVARCHAR(255)) AS TenNhaThau,
CAST(RES.KetQuaDanhGia AS VARCHAR(25)) AS KetQuaDanhGia
FROM [SPC_fn_HSDXKThuat_BangSo4] (' + CAST(#idDuAn AS VARCHAR(20)) + ',' + CAST(#idGoiThau AS VARCHAR(20)) + ',' + CAST(#idDonVi AS VARCHAR(10)) + ') RES
) SRC
PIVOT(MAX(KetQuaDanhGia) FOR TenNhaThau IN (' + #resultString + ')) P
UNION ALL
SELECT *
FROM (
SELECT 2 AS STT
,' + #Str_DanhGia + ' AS NoiDung,
CAST(RES.TenNhaThau AS NVARCHAR(255)) AS TenNhaThau,
CAST(RES.GiaTri AS VARCHAR(25)) AS GiaTri
FROM [SPC_fn_HSDXKThuat_BangSo4] (' + CAST(#idDuAn AS VARCHAR(20)) + ',' + CAST(#idGoiThau AS VARCHAR(20)) + ',' + CAST(#idDonVi AS VARCHAR(10)) + ') RES
) SRC2
PIVOT(MAX(GiaTri) FOR TenNhaThau IN (' + #resultString + ')) P
UNION ALL
SELECT *
FROM (
SELECT 3 AS STT
,' + #Str_XepHang + ' AS NoiDung,
CAST(RES.TenNhaThau AS NVARCHAR(255)) AS TenNhaThau,
CAST(ROW_NUMBER() OVER(ORDER BY GiaTri) AS VARCHAR(25)) AS XepHang
FROM [SPC_fn_HSDXKThuat_BangSo4] (' + CAST(#idDuAn AS VARCHAR(20)) + ',' + CAST(#idGoiThau AS VARCHAR(20)) + ',' + CAST(#idDonVi AS VARCHAR(10)) + ') RES
) SRC2
PIVOT(MAX(XepHang) FOR TenNhaThau IN (' + #resultString + ')) P
';
PRINT #queryString;
EXEC (#queryString);
END
A part of output messages after run stored:
SELECT
1 AS STT,
N'K?t qu? dánh giá tính h?p l? c?a HSÐXTC' AS NoiDung,
CAST(RES.TenNhaThau AS NVARCHAR(255)) AS TenNhaThau,
CAST(RES.KetQuaDanhGia AS VARCHAR(25)) AS KetQuaDanhGia
FROM
[SPC_fn_HSDXKThuat_BangSo4] (60006000000000166, 60006000000000347, 60006) RES
You can see error text: N'K?t qu? dánh giá tính h?p l? c?a HSÐXTC'.
I want to output: Kết quả đánh giá tính hợp lệ của HSĐXTC
How can I fix this?
Change these lines in your procedure:
SET #Str_TinhHopLe = N'Kết quả đánh giá tính hợp lệ của HSĐXTC';
SET #Str_DanhGia = N'Giá đánh giá';
SET #Str_XepHang = N''Xếp hạng các HSDT';
I have table like this
level|value
1 |ABC
1 |XYZ
1 |QWER
2 |1234
2 |7360
3 |zxcv
3 |0001
How can I join each value on level 1 to all level below? Like:
ABC-1234-zxcv
ABC-1234-0001
ABC-7360-zxcv
...
It the number of levels is not fixed:
Declare #select varchar(max) = 'SELECT ',
#from varchar(max) = 'FROM ',
#where varchar(max) = 'WHERE ',
#query varchar(max)= '';
SELECT #select = #select + 't' + cast([level] as varchar(max)) + '.[value]+''-''+',
#from = #from + 'yourTable t' + cast([level] as varchar(max)) + ',',
#where = #where + 't' + cast([level] as varchar(max)) + '.[level] = ' + cast([level] as varchar(max)) + ' AND '
FROM yourTable
GROUP BY [level]
Set #query = SUBSTRING(#select, 1, len(#select) - 5) + ' ' +
SUBSTRING(#from, 1, len(#from) - 1) + ' ' +
SUBSTRING(#where, 1, len(#where) - 4) + ' ORDER BY 1'
EXEC(#query)
If you have always 3 levels, you can do it like this:
select
d1.value + '-' + d2.value + '-' + d3.value
from
data d1
cross join data d2
cross join data d3
where
d1.level = 1 and
d2.level = 2 and
d3.level = 3
order by
1
If the number of levels isn’t fixed, then you'll probably have to use a recursive CTE
I am using PostgreSQL 9.1
I have the following table containing some settings
setting | content
---------------+---------
enabled | True
reenable_time | 1
count_row | 6
count_col | 3
(4 rows)
And I want to have something like this
enabled | reenable_time | count_row | count_col
---------+-----------------+-------------+----------
True | 1 | 6 | 3
(1 row)
Thank you for your answers!
What you need is cross-tabulation (pivoting), aka turning rows into columns.
If you don't want to hardcode "enabled", "reenable_time", etc., you need to use dynamic SQL.
The basic idea goes like this:
SELECT -- Grab the user_account columns.
acc.id,
acc.email,
-- Use max() combined with a case statement to
-- usher individual attribute values into columns.
max(CASE WHEN (attr.attribute_type = 'first-name')
THEN attr.value END) AS fname,
max(CASE WHEN (attr.attribute_type = 'last-name')
THEN attr.value END) AS lname,
max(CASE WHEN (attr.attribute_type = 'title')
THEN attr.value END) AS title
FROM user_account AS acc
-- Join the attribute table /once/.
LEFT JOIN user_attribute AS attr
ON (attr.user_account_id = acc.id)
WHERE (acc.email = 'foo#example.com')
-- Group by the non-pivoted columns
GROUP BY acc.id,acc.email;
Here a link for further information:
https://sykosomatic.org/2011/09/pivot-tables-in-postgresql/
Here an example from my workplace (it's MS-SQL, but you'll get the idea, PostGre doesn't support the pivot command, it's MS proprietary, so you need to use "case when" with "group by"):
-- ===================================================
-- Author: Stefan Steiger
-- Create date: 14.04.2011
-- Last modified: 17.01.2012
-- Description: Übersetzung für Berichte
-- ===================================================
CREATE PROCEDURE [dbo].[sp_RPT_Report_Translation]
#in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
AS
BEGIN
DECLARE
#strSQL NVARCHAR(MAX)
,#strReportName NVARCHAR(1000)
,#strPivotColumns NVARCHAR(MAX)
,#stichtag DATETIME
-- Abrunden des Eingabedatums auf 00:00:00 Uhr
SET #stichtag = CONVERT(DATETIME, #in_stichtag)
SET #stichtag = CAST(FLOOR(CAST(#stichtag AS Float)) AS DateTime)
SET #in_stichtag = CONVERT(varchar(50), #stichtag)
SET NOCOUNT ON;
SET #strReportName = REPLACE(#in_report_name, N'''', '''''')
-- http://geekswithblogs.net/baskibv/archive/2008/07/03/123567.aspx
SELECT
#strPivotColumns = COALESCE(#strPivotColumns, '') + '[' + [RTR_ItemCaption] + '], '
FROM T_RPT_Translations
WHERE (RTR_Status = 1)
AND (RTR_MDT_ID = #in_mandant)
AND
(
(RTR_ReportName = #strReportName)
OR
(RTR_ReportName = 'PARA_ALL')
)
--AND (RTR_ItemCaption != 'RPT_Title')
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '')
ORDER BY RTR_Sort
SET #strPivotColumns = SUBSTRING(#strPivotColumns, 0, LEN(#strPivotColumns))
SET #strPivotColumns = REPLACE(#strPivotColumns, N'''', '''''')
--PRINT #strPivotColumns
SET #strSQL = '
SELECT TOP(1) * FROM
(
SELECT
RTR_ItemCaption
--,RTR_Kurz_' + #in_sprache + '
,RTR_Lang_' + #in_sprache + '
FROM T_RPT_Translations
WHERE (RTR_MDT_ID = ''' + #in_mandant+ ''')
AND
(
(RTR_ReportName = ''' + #strReportName + ''')
OR
(RTR_ReportName = ''PARA_ALL'')
)
--AND (RTR_ItemCaption != ''RPT_Title'')
AND (RTR_Status = 1)
AND (RTR_ItemCaption IS NOT NULL)
AND
(
(RTR_IsFlag != 1)
OR
(RTR_IsFlag IS NULL)
)
AND (RTR_ItemCaption != '''')
) AS SourceTable
PIVOT
(
MAX(RTR_Lang_' + #in_sprache + ')
FOR RTR_ItemCaption IN
( '
+ #strPivotColumns +
' )
) AS PivotTable
--ORDER BY RPT_RM_SO_Bezeichnung, RPT_RM_GB_Bezeichnung, RPT_RM_NutzungGruppeCode
'
DECLARE #ProzedurParameter nvarchar(max)
SET #ProzedurParameter = '
DECLARE #in_mandant varchar(3)
,#in_sprache varchar(2)
,#in_stichtag varchar(50)
,#in_report_name nvarchar(1000)
;
SET #in_mandant = ''' + REPLACE(#in_mandant, '''', '''''') + ''';
SET #in_sprache = ''' + REPLACE(#in_sprache, '''', '''''') + ''';
SET #in_stichtag = ''' + REPLACE(#in_stichtag, '''', '''''') + ''';
SET #in_report_name = ''' + REPLACE(#in_report_name, '''', '''''') + ''';
'
EXECUTE sp_RPT_DEBUG_LOG_ProzedurRun
'sp_RPT_Report_Translation'
,#ProzedurParameter
,#strSQL
,'' --#ProzedurDetail
;
--PRINT #strSQL
EXECUTE (#strSQL)
END
GO