Append zeros to ssis derived column - sql

Hi I am loading data from flat file to my table through SSAS I want to derive a conditional column to append zeros to is numeric data in the zip code column when the length is <5
Derived Column Expression I am using : (CustomerZipCode!="[A-Za-z]")&&(LEN(CustomerZipCode) < 5) ? RIGHT(("00000" + CustomerZipCode),5) : CustomerZipCode
ForExample
the above expression is not working,request to guide me
Thank you.

Is this for SSIS? My last answer assumed that this was an SSAS column because the SSAS tag. If this is a date load via SSIS, you can use a Script Component to do this instead of a Derived Column. The example below uses C# and the CustomerZipCode column will need to be added in the Input Columns pane with the ReadWrite usage type. The TryParse method checks if the column is numeric and will return false if the column contains any text. The String constructor is used to create the zeroesToAppend string, which is set to the number of zeroes below 5 that the length of the column is, and afterwards this is added to the beginning of the column. This will go in the Input0_ProcessInputRow method, which is executed once for each row from the input.
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
int i;
if (int.TryParse(Row.CustomerZipCode, out i) && Row.CustomerZipCode.Length < 5)
{
string zeroesToAppend = new String('0', 5 - Row.CustomerZipCode.Length);
Row.name = String.Concat(zeroesToAppend, Row.CustomerZipCode);
}
}

Related

How to implement CHANGE_TRACKING_IS_COLUMN_IN_MASK in my application?

When working with Change Tracking in SQL Server, you're supposed to use CHANGE_TRACKING_IS_COLUMN_IN_MASK to determine which column was changed when dealing with updates. For example, like so:
DECLARE #last_synchronization_version bigint = ...;
DECLARE #column_id int = ...;
-- The statement below returns 1 if the specified column (#column_id) was changed, otherwise 0.
SELECT CHANGE_TRACKING_IS_COLUMN_IN_MASK(#column_id, SYS_CHANGE_COLUMNS)
FROM CHANGETABLE(CHANGES dbo.MyTable, #last_synchronization_version) AS CT
I wonder, is there a way to implement CHANGE_TRACKING_IS_COLUMN_IN_MASK myself, so I can work with the value of SYS_CHANGE_COLUMNS in my application without having to know beforehand which columns my application is interested in when executing the query?
For example, when I only change the value of the column with ID 11, the value of SYS_CHANGE_COLUMNS is 0x000000000B000000.
How can I programmatically determine that this mask contains the information that column 11 was changed?
It turns out SYS_CHANGE_COLUMNS consists of a byte array that can be grouped into groups of 4 bytes. The more columns were changed, the longer the byte array will be, thus the more groups you can make. The first byte of each group represents an ID of a column that was changed. In all of my tests, the other 3 bytes of each group were empty (0). I assume these bytes will be used when you have a column ID larger than 255. It seems the order in which columns were changed determines the order in which they appear in the byte array. Also, the first group of 4 bytes will always be empty (0), I'm not sure why.
To use this in application code, all you need to do is get a mapping for each column name and it's respective column ID. The previous paragraph should explain how to use SYS_CHANGE_COLUMNS to determine which column ID appears in the byte array.
C# example:
public static IEnumerable<int> GetColumnIdsInMask(byte[] columns)
{
// TODO: deal with column IDs larger than 255
for (var i = 4; i < columns.Length; i += 4)
{
yield return columns[i];
}
}
public static bool IsColumnInMask(int columnId, byte[] columns)
{
return GetColumnIdsInMask.Any(x => x == columnId);
}

Why isn't IIF statement TRUE part evaluating correctly when trying to format Zip codes?

I have a ZipCode field in one of my tables.
Most of the values are typical 5 digit zip codes, however some of them have a dash and an additional 4 digits. The field is set to text data type.
My issue is that I would like to preserve the leading zeroes when appropriate, but not truncate the zip codes that have the additional 4 digits at the end.
The values are currently one of the following (all text data types):
5429
34567
21134-8733
The expected results should be the following:
05429
34567
21134-8733
I have created the below query. It is not working properly, it just returns the original value of the field.
UPDATE [Export file2]
SET [Export file2].ZipCode =
IIf(Len([Export file2].[ZipCode])<6,Format([Export file2].[ZipCode],"00000"),[Export file2].[ZipCode]);
Format will not format a text field, so make the value numeric first:
UPDATE [Export file2] SET [Export file2].ZipCode = IIf(Len([Export file2].[ZipCode])<6,Format(Val([Export file2].[ZipCode]),"00000"),[Export file2].[ZipCode]);
It would greatly help if you could include an example of each type of data you are working with, and the expected result for each.
Assuming I've correctly understood what you are looking to achieve, you can use the Right function in the following way:
UPDATE [Export file2]
SET [Export file2].ZipCode =
IIf
(
Len([Export file2].[ZipCode]) < 6,
Right("00000" & [Export file2].[ZipCode],5),
[Export file2].[ZipCode]
)
Alternatively, if you also want to ensure that the 'other' type of zip codes also have the appropriate leading zeroes (assuming the value will always be at most 10 characters in length), perhaps the following is appropriate:
UPDATE [Export file2]
SET [Export file2].ZipCode =
Right("00000" & [Export file2].[ZipCode], IIf(Len([Export file2].[ZipCode]) < 6,5,10)

Change month name to month number in SSIS

I have a source file which has 50 columns. One of the columns is TransDateTime and the value in it is of format 22-MAY-2017 02:31:15.00. Now before loading this source file to final destination table i want it to be converted to the format 22-05-2017 02:31:15.00 so that i can use the data type datetime for that column.
I have seen ways to convert month name to month number if the column just contains the month value like below.
http://www.techbrothersit.com/2014/11/ssis-how-to-convert-month-name-into.html
I am not sure how to work around this scenario in my case. Any solutions?
Well one solution would be to REPLACE. Simply replace "MAY" with "05" and you get the desired outcome from your sample input.
Nest 12 REPLACE functions in one expression and you will handle every possible scenario.
Use a script component. Convert the input column to your desired format like this in C#:
DateTime.Parse("22-MAY-2017 02:31:15.00").ToString("dd-MM-yyyy HH:mm:ss.ff");
For example, if your input column is MyDate and Out put column is OutPutCol then:
OutPutCol = DateTime.Parse(Row.MyDate).ToString("dd-MM-yyyy HH:mm:ss.ff");
You can check the code here.
If your destination column datatype is datetime, so you are not looking to reformat your date string. but you are looking to convert this string into date value.
You can add a Script COmponent in the dataflow task, with an output column of type DT_DBTIMESTAMP and mark TransDateTime Column as input. and use the following code: (i used VB.NET)
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Output0Buffer)
Row.OutDate = DateTime.ParseExact(Row.TransDateTime,"dd-MMM-yyyy HH:mm:ss.ff",New System.Globalization.CultureInfo("en-GB"))
End Sub
If your destination column is of type string then you have to follow the same steps but the output column should be of type DT_STR and you have to use the following code:
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Output0Buffer)
Row.OutDate = DateTime.ParseExact(Row.TransDateTime,"dd-MMM-yyyy HH:mm:ss.ff",New System.Globalization.CultureInfo("en-GB")).ToString("dd-MM-yyyy HH:mm:ss.ff")
End Sub

access 2007 change the first letter in a field of a table

I have a table called documents one of the fields is called location which shows the file path for the document. I need to change it from D:\........ to H:\.....
How can I do this using update in sql as the file paths vary in length and there are lots of records
You can use string helper function to achieve the same. Something like below
UPDATE documents SET location = 'H:' + Mid(location, 2, Len(location) - 2)
WHERE Left(location, 1) = 'D'
Here, Len() function returns the length of the string literal
Left() function returns 1 character from the left of the string literal
Mid() function give you substring from a string (starting at any position)
See MS Access: Functions for more information on the same.

How to exclude one value from a grouping sum, based on a value of another field?

How do I exclude one value from a grouping sum, based on a value of another field?
ie I open Report=> Report Properties=>Code and insert my Custom Code, but how would I change the below code to exclude a numeric value of another field for the below case?
Public Function ChangeWord(ByVal s As String) As String
Dim strBuilder As New System.Text.StringBuilder(s)
If s.Contains("Others") Then
strBuilder.Replace("Others", "Other NOT INCL")
Return strBuilder.ToString()
Else : Return s
End If
End Function
I'm assuming you want to exclude a numeric value from a sum where the string value of a cell on the same row includes "Others", and that the function you've supplied is used as the grouping criteria for a table in the report. Apologies if this isn't correct.
It's not going to be possible to do this without using a second piece of logic, either a function or an Iif condition. I don't have SSRS available to test this at the moment, but (assuming your value column is an integer, the code will look something like:
Public Function ExcludeOthers(rowDesc As String, rowVal as integer)
if ChangeWord(rowDesc) = "Other NOT INCL"
Return 0
else
Return rowVal
end if
End Function
Then, in the cell where you want the conditional sum to appear:
=Sum(ExcludeOthers(Fields!desc.Value,Fields!val.Value))
Alternatively, you could do this without the function by using Iif in the cell where the conditional sum will appear:
=Sum(Iif(ChangeWord(Fields!desc.Value) = "Other NOT INCL",0,Fields!desc.Value))
Depending on the nature of your source data, you could also do this by adding calculated columns to the report's source query.
I would favour the second or third option - custom code seems like overkill for this purpose.