SSIS Expression equivalent to SQL Expression - sql-server

what is the SSIS equivalent expression(Derived Column component) of the below SQL expression
cast(CASE WHEN len(cast(KPI as varchar(3))) > 2 THEN
CASE substring(cast(KPI as varchar(3)),3,1)
WHEN 1 then left(cast(KPI as varchar(3)),1) + 'a'
WHEN 2 then left(cast(KPI as varchar(3)),1) + 'b'
WHEN 3 then left(cast(KPI as varchar(3)),1) + 'c'
WHEN 4 then left(cast(KPI as varchar(3)),1) + 'd'
END
ELSE cast(KPI as varchar(3))
END as VarChar(3)) as 'ColumnName'
here Kpi column is a double precision floating point data type...
one major thing i have observed here is LEFT String function is missing from SSIS Expression Builder.
SSIS experts please have a look..

I have been trying around 1 hour on my system..finally found the answer..Hope it would be useful to somebody else
created a new column,NewKPI and converted that to dt_str in dataconversion componet (as mentioned by Justin )
(DT_STR,3,1252)(LEN(NewKPI) <= 2 ? NewKPI : (SUBSTRING(NewKPI,3,1) == "1") ? "2A" : (SUBSTRING(NewKPI,3,1) == "2") ? "2b" : (SUBSTRING(NewKPI,3,1) == "3") ? "2c" : (SUBSTRING(NewKPI,3,1) == "4") ? "2d" : NULL(DT_WSTR,3))
(I have used substring instead of Left)
Thanks all for the help

Related

Snowflake with regular expression

Trying to run the below SQL in Snowflake:
SELECT fm_id ,
CASE
WHEN regexp_instr(ASSD,'...',1) > 0
THEN regexp_SUBSTR(ASSD,1,regexp_instr(ASSD,'...',1)-1)
ELSE ASSD
END ASSD
from
(SELECT a.fm_id,
listagg(a.STUID, '; ') within GROUP (
ORDER BY a.Fm_id, a.STUID ) ASSD
from stu_d a
where fm_id = 1222
group by a.fm_id
)
Getting error:
"Invalid parameter value: 0. Reason: Position must be positive"
seems it is failing at -1 or 0 value in above case statement.
What am I doing wrong?
Without seeing your table it's hard to say, but regexp_instr() will return 1 when the pattern is at the beginning of the string. Then, you subtract 1, and 0 is an invalid position argument to regexp_substr(). doc
Perhaps you intended to use SUBSTR not REGEX_SUBSTR()

Case Expression error (NON- Boolean)

I'm getting error when i tried to use case statement please I'm new in SQL Query anyone know where im wrong
An expression of non-boolean type specified in a context where a condition is expected, near 'and'.
You probably want (checking if all columns are true in row):
SELECT
case when (
SIGN(Orcale) * SIGN(Sqlserver) * SIGN(GeoDatabase) * SIGN(Shapefile) *
SIGN(Cadfile) * SIGN(Excel) *SIGN(Word) * SIGN(OtherType)) = 1 then 'u'
ELSE 'Re'
end
FROM tab;
DBFiddle Demo
Assuming, instead of lad2025's answer where all columns are true, that you want to know if ANY column is true, this will work.
SELECT
CASE
WHEN
(Oracle + Sqlserver + GeoDatabase + Shapefile + Cadfile + Excel + Word + OtherType) = 0
THEN 'u'
ELSE 'Re'
END;

Query fails on "converting character string to smalldatetime data type"

I've been tasked with fixing some SQL code that doesn't work. The query reads from a view against a predicate. The query right now looks like so.
SELECT TOP (100) Beginn
FROM V_LLAMA_Seminare
//Removal of the following line makes the query successful, keeping it breaks it
where Beginn > (select cast (getdate() as smalldatetime))
order by Beginn desc
When I run the above query, I am greeted with the following error.
Msg 295, Level 16, State 3, Line 1
Conversion failed when converting character string to smalldatetime data type.
I decided to remove the WHERE clause, and now it runs returning 100 rows.
At first, I thought that behind the scenes, SQL Server was somehow including my predicate when bringing back the View . But then I investigated how the View was being created, especially the Beginn field, and at no point does it return a String.
Long story short, the column that becomes the Beginn field is a BIGINT timestamp like 201604201369.... The original user transforms this BIGINT to a smalldatetime using the following magic.
....
CASE WHEN ma.datum_dt = 0
THEN null
ELSE CONVERT(smalldatetime, SUBSTRING(CAST(ma.datum_dt AS varchar(max)),0,5) + '-' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),5,2) + '-' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),7,2) + ' ' +
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),9,2) +':'+
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),11,2) +':' +
RIGHT(CAST(ma.datum_dt AS varchar(max)),2)) END AS Beginn
...
My last attempt at finding the problem was to query the view and run the function ISDATE over the Beginn column and see if it returned a 0 which it never did.
So my question is two fold, "Why does a predicate break something" and two "Where on earth is this string error coming from when the Beginn value is being formed from a BIGINT".
Any help is greatly appreciated.
This problem is culture related...
Try this and then change the first SET LANGUAGE to GERMAN
SET LANGUAGE ENGLISH;
DECLARE #bi BIGINT=20160428001600;
SELECT CASE WHEN #bi = 0
THEN null
ELSE CONVERT(datetime, SUBSTRING(CAST(#bi AS varchar(max)),0,5) + '-' +
SUBSTRING(CAST(#bi AS varchar(max)),5,2) + '-' +
SUBSTRING(CAST(#bi AS varchar(max)),7,2) + ' ' +
SUBSTRING(CAST(#bi AS varchar(max)),9,2) +':'+
SUBSTRING(CAST(#bi AS varchar(max)),11,2) +':' +
RIGHT(CAST(#bi AS varchar(max)),2)) END AS Beginn
It is a very bad habit to think, that date values look the same everywhere (Oh no, my small application will never go international ...)
Try to stick to culture independent formats like ODBC or ISO
EDIT
A very easy solution for you actually was to replace the blank with a "T"
SUBSTRING(CAST(ma.datum_dt AS varchar(max)),7,2) + 'T' +
Then it's ISO 8601 and will convert...
The solution was found after looking through #Shnugo's comment. When I took my query which contained the Bigint->Datetime conversion logic, and put it into a CTE with "TOP 100000000" to avoid any implicit conversion actions, my query worked. Here is what my view looks like now with some unimportant parts omitted.
---Important part---
CREATE VIEW [dbo].[V_SomeView] AS
WITH CTE AS (
SELECT TOP 1000000000 ma.id AS MA_ID,
---Important part---
vko.extkey AS ID_VKO,
vko.text AS Verkaufsorganisation,
fi.f7000 AS MDM_Nr,
vf.f7105 AS SAPKdnr,
CASE WHEN ma.datum_dt = 0 --Conversion logic
CASE WHEN ma.endedatum_dt = 0 --Conversion logic
CONVERT(NVARCHAR(MAX),art.text) AS Art,
.....
FROM [ucrm].[dbo].[CRM_MA] ma,
[ucrm].[dbo].[CRM_fi] fi,
[ucrm].[dbo].[CRM_vf] vf,
[ucrm].[dbo].[CRM_ka] vko,
[ucrm].[dbo].[CRM_ka] art,
[ucrm].[dbo].[CRM_ka] kat
where ma.loskz = 0
and fi.loskz = 0
and vf.loskz = 0
and fi.F7029 = 0
and vf.F7023 = 0
...
GROUP BY ma.id,
vko.extkey,
vko.text,
fi.f7000 ,
vf.f7105,
ma.datum_dt,
ma.endedatum_dt,
....
)
select * FROM CTE;

Script for automatic creation of DB tables

I have to make a script which creates schema that must have 1.000 tables, with 1.000 columns.
Table name (example): TABLE_058
Column name (example): T058_COL_078
Tables should be empty. I'm working with Oracle DB and ain't too apt with SQL/PL-SQL.
Would be much obliged if someone would point me in right direction.
This will work if you save it as a script and then execute it under SQL*Plus. The tables are named TABLE_000 through TABLE_999 and the columns are similarly sequenced 000 through 999.
SET ECHO OFF
SET TERMOUT OFF
SET TRIMSPOOL ON
SET PAGESIZE 0
SET LINESIZE 2000
SET FEEDBACK OFF
SPOOL C:\CreateTables.sql
SELECT
CASE
WHEN ColIndex = 0 THEN 'CREATE TABLE TABLE_' || TO_CHAR(TableIndex, 'FM000') || ' ('
ELSE NULL
END ||
' T' || TO_CHAR(TableIndex, 'FM000') || '_COL_' || TO_CHAR(ColIndex, 'FM000') || ' VARCHAR2(1)' ||
CASE
WHEN ColIndex = 999 THEN ');'
ELSE ','
END
FROM (
SELECT TableIndex, ColIndex FROM (
SELECT LEVEL - 1 AS TableIndex FROM DUAL CONNECT BY LEVEL <= 1000)
CROSS JOIN (
SELECT LEVEL - 1 AS ColIndex FROM DUAL CONNECT BY LEVEL <= 1000)
ORDER BY TableIndex, ColIndex);
SPOOL OFF
Some things to note:
The numbering scheme is from 000 through 999 because your template for table/column names uses three digits and the only way to get to 1000 tables/columns like that is to start at zero.
Change the filename in SPOOL C:\CreateTables.sql to a filename that works for you.
You didn't specify the column type so the script above has them all as VARCHAR2(1)
It's important to run the above as a script from SQL*Plus. If you don't, a lot of the SQL*Plus chatter will end up in the spooled output. To run the script from SQL*Plus, just type the "at" sign (#) followed by the script's name. If you name it TableGenScript.sql then do this:
SQL> #TableGenScript.sql
The first few lines of output from the script look like this:
CREATE TABLE TABLE_000 ( T000_COL_000 VARCHAR2(1),
T000_COL_001 VARCHAR2(1),
T000_COL_002 VARCHAR2(1),
T000_COL_003 VARCHAR2(1),
Give it a try and you should be able to tweak this to your specific needs.
Addendum NikolaB asked how to vary the column type and the answer is too long to fit in a comment...
To vary the column type, take the part of the query that says || ' VARCHAR2(1)' || and replace it with your data-type logic. For example, if columns 0-599 are VARCHAR2, columns 600-899 are NUMBER, and columns 900-999 are DATE, change the script to something like this:
... all the SETs like above, then the SPOOL ...
SELECT
CASE
WHEN ColIndex = 0 THEN 'CREATE TABLE TABLE_' || TO_CHAR(TableIndex, 'FM000') || ' ('
ELSE NULL
END ||
' T' || TO_CHAR(TableIndex, 'FM000') || '_COL_' || TO_CHAR(ColIndex, 'FM000') ||
CASE -- put the data-type logic in this CASE
WHEN ColIndex BETWEEN 0 AND 599 THEN ' VARCHAR2(1)'
WHEN ColIndex BETWEEN 600 AND 899 THEN ' NUMBER'
ELSE ' DATE'
END || -- data-type logic ends here and original query resumes
CASE
WHEN ColIndex = 999 THEN ');'
ELSE ','
END
FROM
... and then the same as above, all the way through to the SPOOL OFF
I've highlighted the CASE statement with a comment. If you put your data-type logic between the CASE and the END you should be fine.
Export the schema's metadata.
exp userid=user/pass#db owner=someowner rows=n file=somefile.dmp
if you open the file using notepad you could see the DML statements.
you can then import using
imp userid=user/pass#otherdb file=somefile.dmp full=y
you can also copy to another schema on the same db (usually for testing)
imp userid=user/pass#db file=somefile.dmp fromuser=someschema touser=otherschema
you can also use the new datapump for parallel and compression enhancements.
check out this link

test ssis transformation expressions in management studio and creating an expression

I am trying to remove part of a string from another string, for example:
declare #url varchar (20)
set #url = 'www.test.com~~34235645463544563554'
select #url, substring(#url,1,CHARINDEX('~~',#url)-1)
I am trying to remove '~~34235645463544563554'
I am use to using the built in tsql functions (as shown above) to do this but trying to do the same thing in a step in ssis as a "derived column transformation". Can someone suggest how I can do this and whether there is a easy way to quickly test this out in management studio? ie using the expression written in ssis to test for the expected result. I would prefer not to run the whole thing as it is a big package.
In the end I used a script component:
Dim debugOn As Boolean
debugOn = False
If debugOn Then MsgBox(Row.trackingCode)
If Row.trackingCode <> "" Then
' find the delimiter location
Dim endLocation As Integer
If debugOn Then MsgBox("index of ~~ is " & Row.trackingCode.ToString().IndexOf("~~", 0))
' chk if we have ~~ in field, if not in field then -1 is returned
If Row.trackingCode.ToString().IndexOf("~~", 0) > -1 Then
' if ~~ at the beginning ie no tracking code
If Row.trackingCode.ToString().IndexOf("~~", 0) = 1 Then
endLocation = Row.trackingCode.ToString().IndexOf("~~", 0)
ElseIf Row.trackingCode.ToString().IndexOf("~~", 0) > 1 Then
endLocation = Row.trackingCode.ToString().IndexOf("~~", 0) - 1
End If
If debugOn Then MsgBox("end of track code is " & endLocation)
Row.trackingCode = Row.trackingCode.Substring(1, endLocation)
End If
End If

Resources