How to concat variable to other variable in postgresql? - sql

In php connecting variable using . (dot), like $a = "tes", $b="b", if
I connect $a.$b it becomes "tesb". I want this but in postgres
I have tried using dot and + but wrong
my code
CREATE OR REPLACE FUNCTION make_ctx_contoh (rl varchar, dat varchar)
RETURNS numeric AS $total$
declare
date_before date;
dan text;
os_l numeric;
BEGIN
date_before = (DATE_TRUNC('month', NOW())
+ '0 MONTH'::INTERVAL
- '1 DAY'::INTERVAL)::DATE;
if rl = 'nasional' THEN
dan = '';
ELSEIF rl = 'kanwil' THEN
dan = 'AND LOWER(a."KANWIL") = knw';
ELSEIF rl = 'kc' THEN
dan = 'AND LOWER(a."KC") = kac';
END IF;
SELECT
SUM("a"."OUTSTANDING") into os_l
FROM
"public".tbl_nominatif_hasil AS "a"
WHERE
"a"."BUSS_DATE" = date_before AND
"a"."COLLDET" = '1 ' + dan; RETURN os_l;
END; $total$ LANGUAGE plpgsql;
When I run select make_ctx_contoh('kanwil','2'); that shows error like :
ERROR: operator does not exist: unknown + text LINE 6:
"a"."COLLDET" = '1 ' + dan

From what I could understand from your code, you want to add conditions to the where clause based on certain criteria.
So, convert your select query into a AND OR logic.
SELECT
SUM("a"."OUTSTANDING") into os_l
FROM "public".tbl_nominatif_hasil AS "a"
WHERE "a"."BUSS_DATE" = date_before AND
"a"."COLLDET" = 1
AND ( rl = 'nasional' OR
( rl = 'kanwil' AND LOWER(a."KANWIL") = knw) OR
( rl = 'kc' AND LOWER(a."KC") = kac')
)

Related

Save the output of a procedure in snowflake in a variable

I have following procedure:
create or replace procedure todays_delivery_amount(targetkey_variable varchar)
returns number
language sql
as
$$
begin
if ((SELECT MONTHLY_DELIVERED_AMOUNT FROM test.process.msv_month_amount where TARGET_KEY = '20') = 0)
then
return ((SELECT monthly_target_amount from test.process.msv_month_amount)/3) ;
else
return ((SELECT monthly_target_amount from test.process.msv_month_amount where TARGET_KEY = '20') - (SELECT MONTHLY_DELIVERED_AMOUNT from test.process.msv_month_amount where TARGET_KEY = '20')) /
(SELECT (SELECT DATEDIFF(DAY,CONCAT(LEFT(current_date(), 8), '01')::date, CONCAT(LEFT(current_date(), 8), (SELECT datediff(dd,current_date(),dateadd(mm,1,current_date()))))::date+1)
- DATEDIFF(WEEK,CONCAT(LEFT(current_date(), 8), '01')::date, CONCAT(LEFT(current_date(), 8), (SELECT datediff(dd,current_date(),dateadd(mm,1,current_date()))))::date+1)) - RIGHT(current_date() -1, 2)::number + CAST(Round((day( current_date() ) +6)/7,0) as VARCHAR)::number);
end if;
end;
$$
;
UNSET todays_amount;
call todays_delivery_amount('10');
Now I want to do two things:
First I would like to save the output of the procedure in the variable todays_amount
So I tried this:
SET todays_amount = call todays_delivery_amount('10');
But this does not work.
And second:
Instead of where TARGET_KEY = '20' i would like to do where TARGET_KEY = targetkey_variable
But this does not work.
It appears that you can't set it directly from the call statement, but you can do this:
UNSET todays_amount;
call todays_delivery_amount('10');
set todays_amount = (select TODAYS_DELIVERY_AMOUNT from table(result_scan(last_query_id())));

How to use part of a query inside a variable Oracle Function

I'm trying to use a part of a query into a variable , because I have many ifs to prepare the query , but I have not used something like this.
FUNCTION f_rel_vendas_importacao(vTP_DADOS in varchar2, nCODIGO in number, dDT_COMPRA_INI in DATE, dDT_COMPRA_FIM in DATE, dDT_EFETIVACAO_INI in DATE, dDT_EFETIVACAO_FIM in DATE) RETURN number is
nRetorno number(14,2);
vSTRING VARCHAR2(2000);
begin
IF vTP_DADOS = 'VL_COMISSAO' THEN
vSTRING := 'SUM( DECODE( CPF.CD_MOEDA, 1, CPF.VL_COTACAO_UNIT * CPF.QTDE_COMPRA, ( SELECT Imp_Pack.fu_converte_moeda_ORACLE( CPF.CD_MOEDA, 1, CDT.DT_RECEBIMENTO, CPF.VL_COTACAO_UNIT, 1) * CPF.QTDE_COMPRA FROM dual ) ) )';
END IF;
IF vTP_DADOS = 'QTD_VENDA_SELECTCHEMIE_PERIODO' THEN
vSTRING := 'count(*)';
END IF;
SELECT
vSTRING
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
Return nRetorno;
end
f_rel_vendas_importacao;
When you SELECT vString, the result is the content of the variable vString. It doesn't make any attempt to interpret that content as a column or expression. You are best off placing those expressions directly into the query.
IF vTP_DADOS = 'VL_COMISSAO' THEN
SELECT
SUM( DECODE( CPF.CD_MOEDA, 1,
CPF.VL_COTACAO_UNIT * CPF.QTDE_COMPRA,
( SELECT Imp_Pack.fu_converte_moeda_ORACLE( CPF.CD_MOEDA, 1,
CDT.DT_RECEBIMENTO, CPF.VL_COTACAO_UNIT, 1) *
CPF.QTDE_COMPRA
FROM dual ) ) )
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND
CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
END IF;
IF vTP_DADOS = 'QTD_VENDA_SELECTCHEMIE_PERIODO' THEN
SELECT count(*)
INTO
nRetorno
FROM
COMPRA_PROD_FORN CPF,
COMPRA_DATA CDT
WHERE
(CDT.DT_RECEBIMENTO >= dDT_COMPRA_INI AND
CDT.DT_RECEBIMENTO <= dDT_COMPRA_FIM) AND
CDT.CD_COMPRA = CPF.CD_COMPRA AND
CDT.CD_TP_DATA = 7 AND
CPF.CD_FORNECEDOR = nCODIGO;
END IF;

Unix Sql -- Updating One table from a 2nd table -- null value issue

I have been looking at the web for hours trying to determine what is wrong with my code. I keep receiving the ORA-01407: cannot update ("AMIOWN"."MEMBER"."LANGUAGE_X") to NULL. I need to update the language in the member table when the language in the contract table is not null. The 3rd table is required in order to drill down to specific members. Below is the code:
update member m
set language_x =
(select language_x
from contract c
where m.contract_nbr = c.contract_nbr and
c.language_x is not null and
m.member_nbr =
(select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr and
ms.void = ' ' and
ms.carrier = 'PM' and
ms.prog_nbr = 'GP' and
ms.region = 'TR' and
(ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) and
ms.ymdend > 20160218
)
);
Some of the postings also suggested adding another line after the last parenthesis checking for:
where exists (select 1 from contract c where m.contract_nbr = c.contract_nbr and c.language_x is not null);
I am working in a unix environment, tables are contained in an amisys database.
Thank you for any suggestions.
you need to add the where condition to your update statement
update member m
set language_x = (select language_x
from contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
)
where exists (select language_x
from contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
);
Below is a more elegant solution, but depending on your datamodel it might or might not work
Update
(
select m.language_x as oldval
c.language_x as newval
from member m
,contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
) t
set t.oldval =t.newval

Conversion failed when converting the varchar value '*' to data type int

I'm getting this issue when i'm running nested while loops in sql server 2005.
My outer loop gets one iteration, and then my inner loop gets it's full first iteration, but my statement after the inner loop never gets executed, which then seems to break everything.
I'm lost right now and I feel like I'm missing something very easy, any help is much appreciated.
while exists(select top 1 ident from #tmpAttorneyImport (nolock) where parsed = 0 and zipcode <> '')
begin
set #intCurrentIdent = 0
set #vcrCurrentAttonreyName = ''
set #vcrCurrentZip = ''
select top 1 #intCurrentIdent = ident from #tmpAttorneyImport (nolock) where parsed = 0
select #vcrCurrentAttonreyName = ltrim(rtrim(attorneyname)) from #tmpAttorneyImport (nolock) where ident = #intCurrentIdent
select #vcrCurrentZip = ltrim(rtrim(zipcode)) from #tmpAttorneyImport (nolock) where ident = #intCurrentIdent
if(len(#vcrCurrentZip) > 3)
begin
set #vcrMinZip = ''
set #vcrMaxZip = ''
select #vcrMinZip = ltrim(rtrim(left(#vcrCurrentZip, 3)))
select #vcrMaxZip = ltrim(rtrim(right(#vcrCurrentZip, 3)))
while(convert(int, #vcrMinZip) <= convert(int, #vcrMaxZip)) -- sql is telling me this line has the error
begin
insert into #tmpAttorneysFormatted(
attorneyname,
zipcode
)
select
attorneyname = #vcrCurrentAttonreyName,
zipcode = case
when len(#vcrMinZip) = 1 then '00' + ltrim(rtrim(#vcrMinZip))
when len(#vcrMinZip) = 2 then '0' + ltrim(rtrim(#vcrMinZip))
when len(#vcrMinZip) = 3 then ltrim(rtrim(#vcrMinZip))
end
select #vcrMinZip = convert(int, #vcrMinZip) + 1
end
-- this statement does not get hit
update #tmpAttorneyImport
set
parsed = 1
where
ident = #intCurrentIdent
end
else
begin
insert into #tmpAttorneysFormatted(
attorneyname,
zipcode
)
select
attorneyname = #vcrCurrentAttonreyName,
zipcode = case
when len(#vcrCurrentZip) = 1 then '00' + ltrim(rtrim(#vcrCurrentZip))
when len(#vcrCurrentZip) = 2 then '0' + ltrim(rtrim(#vcrCurrentZip))
when len(#vcrCurrentZip) = 3 then ltrim(rtrim(#vcrCurrentZip))
end
update #tmpAttorneyImport
set
parsed = 1
where
ident = #intCurrentIdent
end
end
select #vcrMinZip = ltrim(rtrim(left(#vcrCurrentZip, 3)))
select #vcrMaxZip = ltrim(rtrim(right(#vcrCurrentZip, 3)))
How sure are you that your data is clean?
I'd put in (right after this) two lines:
print #vcrMinZip
print #vcrMaxZip
and see what is actually being parsed out of the string.

Remove SQL comments

our stored procedures have developer comments and headers and as part of our deployment process we would like to remove these from the customer copy. Is there a method of achieving this within SQL Server 2005 or with another tool?
Don't know if it would suit, but you can use the WITH ENCRYPTION option to hide the entire contents. Do your end users need to see/modify any of the procedures?
I use an SQL tool called WinSQL (very handy, highly reccommended) that has an option to "Parse Comments Locally".
I don't use it much personally, but I have had it on accidentally when running my scripts that build my stored procs and it does clean them out of the proc source in the database. :-)
Even the free version has that option.
This option wasn't available when the question was asked, but in SQL 2012, we can now use SQL Server's own parser to help us out.
Removing Comments From SQL
A little late to the party but in case someone else stumbles across...
CREATE FUNCTION [usf_StripSQLComments] ( #CommentedSQLCode VARCHAR(max) )
RETURNS Varchar(max)
/****************************************************************************************
--######################################################################################
-- Mjwheele#yahoo.com -- Some count sheep. Some code. Some write code to count sheep.
--######################################################################################
--#############################################################################
-- Sample Call Script
--#############################################################################
Declare #SqlCode Varchar(Max)
Declare #objname varchar(max) = 'sp_myproc'
select #Sqlcode = OBJECT_DEFINITION(t.OBJECT_ID)
from sys.objects t
where t.name = #objname
select dbo.ssf_StripSQLComments( #Sqlcode )
****************************************************************************************/
AS
BEGIN
DECLARE #Sqlcode VARCHAR(MAX) =#CommentedSQLCode
Declare #i integer = 0
Declare #Char1 Char(1)
Declare #Char2 Char(1)
Declare #TrailingComment Char(1) = 'N'
Declare #UncommentedSQLCode varchar(Max)=''
Declare #Whackcounter Integer = 0
Declare #max Integer = DATALENGTH(#sqlcode)
While #i < #max
Begin
Select #Char1 = Substring(#Sqlcode,#i,1)
if #Char1 not in ('-', '/','''','*')
begin
if #Char1 = CHAR(13) or #Char1 = CHAR(10)
Select #TrailingComment = 'N'
Else if not (#Char1 = CHAR(32) or #Char1 = CHAR(9)) and #TrailingComment = 'N' -- Not Space or Tab
Select #TrailingComment = 'Y'
if #Whackcounter = 0
Select #UncommentedSQLCode += #Char1
select #i+=1
end
else
begin
Select #Char2 = #Char1
, #Char1 = Substring(#Sqlcode,#i+1,1)
If #Char1 = '-' and #Char2 = '-' and #Whackcounter = 0
Begin
While #i < #Max and Substring(#Sqlcode,#i,1) not in (char(13), char(10))
Select #i+=1
if Substring(#Sqlcode,#i,1) = char(13) and #TrailingComment = 'N'
Select #i+=1
if Substring(#Sqlcode,#i,1) = char(10) and #TrailingComment = 'N'
Select #i+=1
End
else If #Char1 = '*' and #Char2 = '/'
Begin
Select #Whackcounter += 1
, #i += 2
End
else If #Char1 = '/' and #Char2 = '*'
Begin
Select #Whackcounter -= 1
, #i += 2
End
else if #char2 = '''' and #Whackcounter = 0
begin
Select #UncommentedSQLCode += #char2
while Substring(#Sqlcode,#i,1) <> ''''
Begin
Select #UncommentedSQLCode += Substring(#Sqlcode,#i,1)
, #i +=1
end
Select #i +=1
, #Char1 = Substring(#Sqlcode,#i,1)
end
else
Begin
if #Whackcounter = 0
Select #UncommentedSQLCode += #Char2
Select #i+=1
end
end
End
Return #UncommentedSQLCode
END
You may want to check this out:
Remove Comments from SQL Server Stored Procedures.
Note: this doesn't handle comments that start with --, which SQL Server allows. Otherwise I would inquire into having a developer write a short filter app that reads the text in via a stream, and then remove the comments that way. Or write it yourself.
I ended up writing my own SQL comment remover in C#
I assume you save your procedure definitions to a text or .sql file that you then version control. You could always use something like notepadd++ to find/replace the strings you want then commit them as a production/customer tag. This is not elegant, but an option. I don't know of any third party tools and my google searches returned the same result as the other posters posted.
You can remove comments using regular expressions in C# like described here. It works for line comments, block comments, even when block comments are nested, and it can correctly identify and ignore comments delimiters when they are inside literals or bracketed named identifiers.
This a VB.NET code for removing SQL Coments
It's supposed the script is well formated syntaxicly under SQL Management Studio
Module Module1
Const TagBeginMultiComent = "/*"
Const TagEndMultiComent = "*/"
Const TagMonoComent = "--"
Public Fail As Integer
Function IsQuoteOpened(ByVal Value As String) As Boolean
Dim V As String = Replace(Value, "'", "")
If V Is Nothing Then Return 0
Return ((Value.Length - V.Length) / "'".Length) Mod 2 > 0
End Function
Function RemoveComents(ByVal Value As String) As String
Dim RetVal As String = ""
Dim Block As String
Dim Tampon As String
Dim NbComentIncluded As Integer = 0
Dim QuoteOpened As Boolean
Dim CommentOpen As Boolean
While Value.Length > 0
Tampon = ""
Block = ""
Dim P1 As Integer = InStr(Value, TagBeginMultiComent)
Dim P2 As Integer = InStr(Value, TagEndMultiComent)
Dim P3 As Integer = InStr(Value, TagMonoComent)
Dim Min As Integer
If P1 = 0 Then P1 = Value.Length + 1
If P2 = 0 Then P2 = Value.Length + 1
If P3 = 0 Then P3 = Value.Length + 1
Tampon = ""
If P1 + P2 + P3 > 0 Then
Min = Math.Min(P1, Math.Min(P2, P3))
Tampon = Left(Value, Min - 1)
Block = Mid(Value, Min, 2)
Value = Mid(Value, Min)
End If
If NbComentIncluded = 0 Then QuoteOpened = IsQuoteOpened(RetVal & Tampon)
If Not QuoteOpened Then
NbComentIncluded += -(Block = TagBeginMultiComent) + (Block = TagEndMultiComent)
If Block = TagMonoComent Then
Dim Ploc As Integer = InStr(Value, vbCrLf)
If Ploc = 0 Then
Value = ""
Else
Value = Mid(Value, Ploc - 2)
End If
End If
End If
If Not CommentOpen And NbComentIncluded = 0 Then
RetVal += Tampon
If ({TagBeginMultiComent, TagEndMultiComent, TagMonoComent}.Contains(Block) And QuoteOpened) Or
(Not {TagBeginMultiComent, TagEndMultiComent, TagMonoComent}.Contains(Block) And Not QuoteOpened) Then RetVal += Block
End If
CommentOpen = (NbComentIncluded > 0)
Value = Mid(Value, 3)
End While
Fail = -1 * (IsQuoteOpened(RetVal)) - 2 * (NbComentIncluded > 0)
If Fail <> 0 Then RetVal = ""
Return RetVal
End Function
Sub Main()
Dim InputFileName = "C:\Users\godef\OneDrive - sacd.fr\DEV\DelComentsSql\test.txt" '"C:\Users\sapgy01\OneDrive - sacd.fr\DEV\DelComentsSql\test.txt"
Dim Script As String = File.ReadAllText(InputFileName)
Dim InputDataArray As String() = Split(Script, vbCrLf)
Script = RemoveComents(Script)
If Fail Then
Console.WriteLine($"Fail : {Fail}")
If Fail And 1 = 1 Then Console.WriteLine("Toutes les quotes ne sont pas refermées")
If Fail And 2 = 2 Then Console.WriteLine("Tous les commentaires multiliqnes ne sont pas refermées")
Else
Console.WriteLine(Script)
End If
Console.ReadKey()
End Sub
End Module
Addon : a check is made for unclosed multilines coment and/or unclosed apostroph.
Example :
/* Commentaire principal
Suite du commentaire principal
/* Inclusion de commentaire
Suite du commentaire inclu
*/ suite commentaire principal
continuation commentaire principal
/* mono comentaire tagué multi lignes */
*/ select * from ref
-- mono commentaire
select ref.ref_lbl_code as 'code
de
la
-- ref --
' -- from ref as 'references' -- Fin de séquence
from ref as reference -- Mono commentaire fin de ligne
go -- lance l'exécution
select dbo.ref.REF_LBL_CODE as 'commentaire
/* Mulitlignes sur une ligne dans litteral */'
from ref as 'table_ref'
select ref.ref_lbl_code as 'commentaire
/* Mulitlignes
sur plusieurs lignes
dans litteral */'
from ref as '-- ref_table --'
-- Fin de l'exécution du ' -- script -- '