Monday, August 21, 2017

Get first name and initial of last name

Sometimes names are longer than convenient for displaying in tables and graphs, so you may consider making them shorter.

Considering the name "Jonathan White" as example, here are a few tips for you:

Only first name

SELECT LEFT(Name, CHARINDEX(' ', Name) - 1)
"Jonathan"

First name plus initial of last name

SELECT LEFT(Name, CHARINDEX(' ', Name) + 1)
"Jonathan W"

Just initials

SELECT  SUBSTRING(Name, 1, 1) + SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 1)
"JW"

Notes

There are some caveats with the above suggestions. They may not work as expected if:
  • If there is only one name, e.g. "Peter"
  • If there is more than 2 names, e.g. "Jennifer Alexandra Smith"
For more advanced processing a UDF (function) or SP (procedure) is probably better adviced.

Wednesday, October 14, 2015

Day of week calculation

With SQL Server you can get the day in week using this simple code:

SELECT DATEPART(weekday, getdate())
This gives you a number from 1 to 7, corresponding to the day in the week.

But which day is the first day in the week?

If you are European - it's Monday.
If you are American - it's Sunday.
If you are SQL Server - it depends...

There's a setting in SQL Server that controls this behavior and perhaps it is not set to your liking. And perhaps you don't want to change it and run the risk of side-effects - or perhaps you simply don't have the permissions.

Despair not!

This simple code will allow you to get the day in week independent of SQL Server's settings:

European:
SELECT (DATEDIFF(dd, DATEADD(YEAR, 0, 0), getdate()) + 1) % 7

American:
SELECT (DATEDIFF(dd, DATEADD(YEAR, 0, 0), getdate()) + 2) % 7

Tuesday, March 3, 2015

How to create lookup views for enum types in ERP system

Problem

Quite often we have to include fields in our data model that have no lookup table in the ERP system. They are usually some kind of "Type" and they are sometimes referred to as "Enum" types in the ERP system.

They have their text values stuck somewhere inside the ERP application layer rather than in real database tables.

Also often it is not desirable to create physical tables in ERP database. And even if we could they would be separated from both the ERP system and the data model we are creating, living their own lives so to speak.

So how do we get a lookup table with the text values corresponding to the enum types?

Solution

One possible solution to this is to create a Dynamic View in Modeller and simple create the record synthetically - with no physical tables involved.

All you need is the ERP system to look up the text values you need and then enter them in the Dynamic View.

Example

Let's say we have an enum called "LineType", which has these values:

0: Item
1: Text

We can create a Dynamic View for these values with this SQL:

SELECT 0 AS LineType_ID, 'Item' AS LineType_Name
UNION ALL
SELECT 1, 'Text'

For practical purposes there will usually be more than 2 values of your enum, so just keep adding "UNION ALL... SELECT..." statements for all the values you need.


That's all. Enjoy!

Thursday, February 13, 2014

Antivirus system makes loading of project very slow

If you observe that Acinta Modeller, Datashop og Enterprise Manager take a very long time to connect to and load metadata then the cause may be an installed antivirus system.

This problem was observed at a customer that had Trend Micro antivirus running.

Just connecting to metadata (after entering login) could take several minutes.
Loading the project - well, we had better things to do.

When we turned off Trend Micro antivirus, all worked normal.

 SOLUTION 

  1. Turn off the antivirus system, or the parts hereof that cause the problem, or
  2. Add the Acinta applications to the antivirus system's "White-list"
For more details about Trend Micro and how to add applications to it's white-list, follow this link:

Thursday, December 13, 2012

Installing on SQL Server 2000

If you need to install Acinta Shortcut on a SQL Server 2000 then there are a couple of changes you need to make. They are briefly described below.

Views

  1. "Acinta_Split" not supported. You'll see an error like this: "Syntax error near a". Acinta_Split is used to decipher "Tælleværker" in C5. Table-valued functions are not supported by SQL Server 2000. You have to remove/comment out all SELECT statements using this function. As a result, you'll not be able to see the results of "Tælleværker".
  2. Top N not supported. A couple of places contain sub-queries in the form:
    SELECT TOP 1 <Expr>
    .....
    ORDER BY ....

    This must be rewritten to:
    SELECT MAX(<Expr>)
    .....

    These functions were introduced in SQL Server 2005.
    How to solve: Replace TOP 1 with MAX( ) and remove the ORDER BY clause.
  3. Row_number() and RANK not supported. In one place these functions are used. There is no simple way to express this function in SQL Server 2000 so the simplest solution is to replace the whole expression by "NULL". If you need this function you'll have to rewrite it yourself. However, it is rarely used so don't worry.

Indexes

Indexes in SQL Server 2000 don't allow the INCLUDE columns. You have to rewrite the indexes and put all needed columns in the main index part. Remember there's a limit of 16 fields per index.

In addition, the "WITH" sub-clause specifying index options, is not supported and must be removed.

For example you have to rewrite this index:
CREATE NONCLUSTERED INDEX [ACINTA_IX_ProjTrans] ON [dbo].[PROPOST]
(
[DATASET] ASC,
[DATO] ASC,
[LXBENUMMER] ASC,
[NUMMER] ASC,
[ART] ASC,
[VARENUMMER] ASC,
[LOKATION] ASC,
[MEDARBEJDER] ASC,
[ENHED] ASC,
[BUDGETKODE] ASC,
[TRANSAKTION] ASC,
[VALUTA] ASC,
[PROTYPE] ASC,
[KOPIERET] ASC,
[OVERFXRTLXN] ASC
)
INCLUDE ( [ANTAL],
[KOSTBELXB],
[TEKST],
[BELXBVAL],
[BELXBSTD],
[DRIFTSFXRTANTAL],
[DRIFTSFXRTBELXBVAL],
[DRIFTSFXRTBELXBSTD],
[KURS],
[DRIFTFXRTLXNTILLXGVAL],
[DRIFTFXRTLXNTILLXGSTD]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

to something like this:
CREATE NONCLUSTERED INDEX [ACINTA_IX_ProjTrans] ON [dbo].[PROPOST]
(
[DATASET] ASC,
[DATO] ASC,
[NUMMER] ASC,
[ART] ASC,
[VARENUMMER] ASC,
[LOKATION] ASC,
[MEDARBEJDER] ASC,
[BUDGETKODE] ASC,
[TRANSAKTION] ASC,
[VALUTA] ASC,
[PROTYPE] ASC,
[OVERFXRTLXN] ASC,
[ANTAL],
[KOSTBELXB],
) ON [PRIMARY]
GO

Other considerations

How do I know which SQL Server version it is?

In order til check the version of SQL Server you need to open SQL Server Management Studio (or Enterprise Manager for older versions) and connect to the server.
The internal version number can be read in the red box: 10.
The internal version numbers have this meaning:
8: SQL Server 2000
9: SQL Server 2005
10: SQL Server 2008
11: SQL Server 2012

Beware of "Compatibility mode"!

SQL Server provides a feature called "Compatibility mode" that enables a newer version of SQL Server to pretend it is an older version. The background for this obscurity is of course to allow older applications to work seamless with newer versions of SQL Server that they were not designed for.

Thus, what may at first sight look like e.g. SQL Server 2008 could in fact be an SQL Server 2000. Or actually it is not that simple. When SQL Server runs in compatibility mode for SQL Server 2000 then the following applies:
  1. It does not recognize newer SQL features such as "TOP" and "Row_number( )". Thus, the fix for these features applies.
  2. It will allow you to create table-value functions (Acinta_Split) but it won't let you use them, thus the remedy for this applies.
  3. It still allows you to create indexes with Included columns. So there's no need to rewrite indexes!
One last thing to consider is whether the compatibility mode is actually correct or if it should be set to the actual version. But you have to verify this; if you change the compatibility mode it may cause some applications to malfunction!

Tuesday, July 10, 2012

Installing on C5 with non-standard schema (not 'dbo')

If you need to install Acinta on a C5 that has been installed with a non-standard schema then you need to make some adjustments to the installation procedure as described below.

How do I know that C5 is installed with a non-standard schema?

When you look at the C5 tables in SQL Server Management Studio you will see that all tables have a pre-fix that is different than 'dbo'.
For example, the table "SALESLINE" could look like this:
c5_supervisor.SALESLINE

instead of this:
dbo.SALESLINE

How do I install on a non-standard schema?

To install Acinta on such a C5 you need to follow the normal installation procedure with these extra steps:
  1. Update Index script. Before installing the indexes you must perform a search-and-replace in the index script where you replace all occurrences of 'dbo.' with the actual schema name.
  2. Rename tables in Modeller. When you open the project in Modeller initially, Modeller will start the Rename wizard because it can't find the tables it is looking for. All you have to do is to follow the instructions on the screen. For example Modeller will tell you: "The table dbo.SALESLINE no longer exists. Do you want to replace it?" and then in the list of tables below you simply select the proper replacement table - c5_supervisor.SALESLINE in this example - and click "Rename"
  3. Update Dynamic Views. You have to locate all dynamic views in Modeller's Warehouse section. Right-click on the dynamic view table's header and choose "Edit Dynamic View SQL" from the context menu. Review the SQL and make sure all table references use the correct schema prefix

Wednesday, May 9, 2012

"Syntax error near a" and the Acinta_Split() function

I have come across this error while compiling the view/dynamic view "ACINTA_DV LedgerOfAccountsRelation" in the C5 data model:
"Syntax error near a".

It happens in this line of the view:

    SELECT COUNT(*)
    FROM Acinta_Split(';', a.TXLLEVXRK) x



The error occurs because SQL Server does not recognize the function "Acinta_Split", which is part of the Acinta Shortcut package.

Now, the function was actually compiled and present in the system, so the error seems mysterious at first.
It turns out that the database was configured to have compatibility level 80 = SQL Server 2000.

And since table-based functions were introduced in SQL Server 2005 it is also the natural explanation why SQL Server throws a syntax error at us.

Solution

To get out of this error you have two choices:

  1. Set the compatibility level of the database to at least 90 (SQL Server 2005)
  2. Comment out the parts of the view that make use of the Acinta_Split function. Block comments have the form: "/* <commented code> */
Obviously, you should choose solution 1. whenever possible. But under some circumstances this is not possible. One such circumstance is when you have a C5 version 3.0 solution, because this version of C5 is only compatible with SQL Server 2000; It does not work with later versions of SQL Server.

Applies to

Please note that this error and its solution applies generally and not just to the C5 solution. I.e. it may apply to:
  • Acinta Shortcut for C5
  • Acinta Shortcut for Ax
  • Acinta Shortcut for Nav
  • Acinta Shortcut for XAL
  • Acinta Shortcut for Visma

Wednesday, April 18, 2012

Datashop crashes at startup


If you are experiencing that Datashop crashes before it even displays its splash screen and you get a message from Windows that the application crashed then the cause is probably restrictions on the user's permissions.


The possible scenario is that you are trying to make an installation without running the Acinta installer, e.g. a network installation. The installation works fine for you (because you use a classified account, e.g. Administrator) but it fails on end-users' PCs.

 SOLUTION   Right-click on the exe-file or shortcut and choose "Run as administrator...". You only need to do this once. Next time you open Datashop it will work fine.

Friday, March 30, 2012

Project takes long time to load - slow loading


Sometimes when you have installed a new project or you are opening the project from a different computer you may experience that the loading of the project is notably slow.

There are several possible causes for this problem.

Possible causes

Old version of Acinta Intelligence Suite

Check if the version of Intelligence Suite you are trying to open is up to date. If metadata was edited using a newer version then it may have stored properties that are not understood by older versions. When this happens, an error trapping mechanism is invoked that writes all the unrecognized properties to the log file. You can verify the problem by investigating the log file.

SOLUTION  Update the .exe files to a new version.


Upgrade to Acinta Intelligence Suite 2014

If you recently upgraded to Acinta Intelligence Suite 2014 from an older version then the problem may be caused by obsolete properties in metadata. I.e. properties that are no longer supported by the new version. Such properties cause internal validation errors and a lot of writing to the log-files.

SOLUTION  You must "clean" the metadata by loading the project in Modeller and run the "Repair" utility and then save the project. It is best to use the option "Save all objects" but it may take somewhat longer to process.


Slow network

A lot of metadata must be transferred over the network when Datashop, Modeller etc. opens a project. A slow network may cause this process to take a very long time. Note: Look out for wireless networks since these are notably slower than wired networks.


SOLUTION  Wire the PC to a cable or upgrade/fix problems in the (wireless) network.

Too little RAM

If the server has too little RAM to fit all the running processes inside then some memory will be mapped to disk. Since disks are multitudes slower than RAM this will inevitably lead to prolonged load times during start-up because thousands of dynamic objects are created representing metrics, dimensions, dashboards etc. This problem is typical of virtual machines where RAM is often a scarce resource to be shared across many virtual machines.


SOLUTION  Enhance the server with more RAM. If the server is a virtual machine it should be considered whether the RAM is dedicated to the server or dynamically shared. Dedicated RAM is better.


Antivirus system interference

Antivirus software such as Trend Micro may cause the project to load extremely slow due to dynamic scanning of running processes.

SOLUTION  Turn off the antivirus system or the parts hereof that cause the problem, e.g. "process scanning". Or perhaps better: Add the Acinta applications (Datashop, Modeller etc.) to the antivirus' so-called White-list to prevent the AV software from scanning these applications at run-time.

Friday, January 13, 2012

Fiscal/financial year date calculations

As a followup to my previous article on calculation of dynamic dates I will demonstrate how we can make similar calculations that take the company's financial year into consideration.

This is important for companies that have a financial year that is not coinciding with the calendar year. In Denmark the financial year typically starts at the beginning of a quarter, i.e.:

  • 1st of January
  • 1st of April
  • 1st of July, or
  • 1st of October

Thus, if in our dashboard we want to use a "year-to-date" filter then we actually want the filter to span from the beginning of the financial year till today's date.

Such a filter condition can be implemented using this SQL:

DATEADD(dd, 0, DATEADD(mm, 6, DATEADD(yy, CASE WHEN MONTH(getdate()) >= 7 THEN YEAR(getdate()) ELSE YEAR(getdate()) - 1 END - 1900, 0)))
The result of this expression (assuming today's date is January 13th 2012) is:
'2011-07-01'
i.e. an ISO formatted date, which should be valid in any SQL Server.

The above example assumes that the financial year starts on July 1st, but obviously you can use the approach for any start day of the financial year.

To change the starting month of the financial year you simple have to modify the script in two places:

  • 6: Replace this value with the last month in the financial year
  • 7: Replace this value with the first month in the financial year


Filter modifiers
As usual, date functions are very useful with filter modifiers. Using a filter modifier you can implement a report where the user selects a date and then your filter modifier transforms the selection into a "year-to-date" date range using the user's selection.

To use the above script in a filter modifier you simply have to replace the occurences of "getdate()" with the desired filter modifier placeholder, {Value1} or {Value2}.

I.e. you need to use this variation of the SQL expression:

DATEADD(dd, 0, DATEADD(mm, 6, DATEADD(yy, CASE WHEN MONTH({Value1}) >= 7 THEN YEAR({Value1}) ELSE YEAR({Value1}) - 1 END - 1900, 0)))

Tuesday, December 6, 2011

How to calculate dynamic dates in SQL Server

Quite often we need to calculate some kind of dynamic date based on the current date or the user's selection in a date filter. Examples include "First day of the year", "First day of the month" and so on.

To help you build such date formulas I have assembled a set of useful calculations for you to use.

Note: To use the calculations in Filter Modifiers you simply replace "getdate()" with the desired filter placeholder, e.g. "{Value1}".

First Day of Month

DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)

Monday of the Current Week

DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)

First Day of the Year

DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)

First Day of the Quarter
DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)

Midnight for the Current Day
DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)

Last Day of Prior Month
DATEADD(dd,-1,DATEADD(mm, DATEDIFF(mm,0,getdate() ), 0))

Last Day of Prior Year
DATEADD(dd,-1,DATEADD(yy, DATEDIFF(yy,0,getdate() ), 0))

Last Day of Current Month
DATEADD(dd,-1,DATEADD(mm, DATEDIFF(m,0,getdate() )+1, 0))

Last Day of Current Year
DATEADD(dd,-1,DATEADD(yy, DATEDIFF(yy,0,getdate() )+1, 0))

First Monday of the Month
DATEADD(wk, DATEDIFF(wk,0, dateadd(dd,6-datepart(day,getdate()),getdate())), 0)

First Day of the Month 12 Months Ago
DATEADD(mm, DATEDIFF(mm,0,getdate()) - 12, 0)
Note: You can change "12" to any number of months ago you wish.

Tuesday, December 7, 2010

Fejl: "Repository databases are not correctly configured" - problem med danske tegn

Hvis du får beskeden:
---------------------------
Warning
---------------------------
Repository databases are not correctly configured.
You may re-configure repository from menu: File|Configure repository.

når du åbner Datashop/Modeller, så skyldes det muligvis problemer med tegnsæt og ukendte tegn i Projects.dspx filen.


Åbn din Projects.dspx fil og kontrollér den for danske bogstaver og andre specialtegn og fjern dem.


En anden mulighed - men dette har jeg dog ikke testet - er at gemme filen i utf8 Unicode format.

Sunday, November 28, 2010

ISO ugenumre i AcTimeDim - rettelse til fejl i ugenumre

Nogle ældre versioner af metadata havde desværre fejl i ugenumrene.
Det er let at rette ugenumrene til korrekte ISO ugenumre, dvs. de ugenumre, der anvendes bredt i Europa med nedenstående scripts:


For at rette ugenumrene skal du gøre flg.:

1.       Åbn SQL Server Management Studio
2.       Åbn en query
3.       Vælg databasen ”AcintaXXMeta” (NN er systemnavnet)
4.       Indsæt nedenstående SQL og eksekvér det

create function dbo.F_ISO_WEEK_OF_YEAR
  (
  @Date      datetime
  )
returns int
as
/*
Function F_ISO_WEEK_OF_YEAR returns the
ISO 8601 week of the year for the date passed.
*/
begin
declare @WeekOfYear int
select
  -- Compute week of year as (days since start of year/7)+1
  -- Division by 7 gives whole weeks since start of year.
  -- Adding 1 starts week number at 1, instead of zero.
  @WeekOfYear =
  (datediff(dd,  case  -- Case finds start of year
    when NextYrStart <= @date then NextYrStart
    when CurrYrStart <= @date then CurrYrStart
    else PriorYrStart
  end,@date)/7)+1
from
  (
  select
  -- First day of first week of prior year
    PriorYrStart =
      dateadd(dd, (datediff(dd,-53690,dateadd(yy,-1,aa.Jan4))/7)*7,-53690),
  -- First day of first week of current year
    CurrYrStart =
      dateadd(dd,(datediff(dd,-53690,aa.Jan4)/7)*7,-53690),
  -- First day of first week of next year
    NextYrStart =
      dateadd(dd,(datediff(dd,-53690,dateadd(yy,1,aa.Jan4))/7)*7,-53690)
    from
    (
       select
       --Find Jan 4 for the year of the input date
         Jan4 =
dateadd(dd,3,dateadd(yy,datediff(yy,0,@date),0))
    ) aa
  ) a
return @WeekOfYear
end

go

UPDATE AcTimeDim
SET CalendarWeek = CAST(CASE WHEN (dbo.F_ISO_WEEK_OF_YEAR(AcDate) > 50) AND(Month(AcDate) = 1) THEN YEAR(AcDate) - 1 ELSE YEAR(AcDate)
END AS CHAR(4)) + '-' + RIGHT('0' + CAST(dbo.F_ISO_WEEK_OF_YEAR(AcDate) AS VARCHAR(2)), 2)