Showing posts with label condition. Show all posts
Showing posts with label condition. Show all posts

Tuesday, March 20, 2012

"WHERE" condition in MSSQL2005 diff. with Oracle DB

Hi,

I got one question about MSSQL2005.

I am using "Microsoft SQL Server Migration Assistant for Oracle" to migrate Oracle Database to Microsoft SQL server 20005.

[Oracle DB]

In Oracle DB, there are two records in table

CREDITOR_ID CREDIT_ID CREDIT_LIMIT CREDIT_BALANCE CREDIT_ONHAND ACCTSTATUSID CREDITTERMSID EDIT_TIME Record 1 YT4996 XX 1 0 0 A 15 1/1/1999 14:10 Record 2 YT4996 XX 2 0 0 B 30 1/1/1998 17:21

In record 1, CREDITOR_ID='YT4996 ', there is a space after string 'YT4996'.

In record 2, CREDITOR_ID='YT4996', there is no space after string 'YT4996'.

SQL(1)

select xxx from CUSTOMER_ID='YT4996'

--> output 1 rows.

SQL(2)

select xxx from CUSTOMER_ID='YT4996 '

--> output 1 rows.

[MSSQL2005]

After migrate data to MSSQL, there are two identical records as Oracle DB.

CREDITOR_ID CREDIT_ID CREDIT_LIMIT CREDIT_BALANCE CREDIT_ONHAND ACCTSTATUSID CREDITTERMSID EDIT_TIME Record 1 YT4996 XX 1 0 0 A 15 1/1/1999 14:10 Record 2 YT4996 XX 2 0 0 B 30 1/1/1998 17:21

In record 1, CREDITOR_ID='YT4996 ', there is a space after string 'YT4996'.

In record 2, CREDITOR_ID='YT4996', there is no space after string 'YT4996'.

SQL(1)

select xxx from CUSTOMER_ID='YT4996'

--> output 2 rows.

SQL(2)

select xxx from CUSTOMER_ID='YT4996 '

--> output 2 rows.

Question:

==> In Oracle DB, 'YT4996 ' <> 'YT4996'

==> In MSSQL2005, 'YT4996 ' = 'YT4996'

Do any setting, affect MSSQL2005, make 'YT4996 ' = 'YT4996' ?

I want MSSQL2005 behaviour as Oracle....

Anyone have hint?

You must have defined the datatype for the column as varchar. This will force sqlserver to strip the trailing blank spaces. If you change the datatype to char, the trailing spaces will be preserved.|||

Thanks for info.

The column is defined as varchar(12).

but I cannot use char(12), since this column will contain variable width data, e.g. 'WT123', 'WT123456'.

If using char(12), all records in this column will become

'WT123 '

'WT123456 '

which will waste space when using char(12).

|||

"Set Ansi_Padding ON" (non-default) before creating the column will force the trailing blanks not to be truncated. This setting needs to be set also during your execution if you decide to create varchar variables and preserve the trailing blanks.

Here is a good example (from bol):

Code Snippet

SET ANSI_PADDING ON
GO
PRINT 'Testing with ANSI_PADDING ON'
GO

CREATE TABLE t1
(charcol char(16) NULL,
varcharcol varchar(16) NULL,
varbinarycol varbinary(8))
GO
INSERT INTO t1 VALUES ('No blanks', 'No blanks', 0x00ee)
INSERT INTO t1 VALUES ('Trailing blank ', 'Trailing blank ', 0x00ee00)

SELECT 'CHAR'='>' + charcol + '<', 'VARCHAR'='>' + varcharcol + '<',
varbinarycol
FROM t1
GO

SET ANSI_PADDING OFF
GO
PRINT 'Testing with ANSI_PADDING OFF'
GO

CREATE TABLE t2
(charcol char(16) NULL,
varcharcol varchar(16) NULL,
varbinarycol varbinary(8))
GO
INSERT INTO t2 VALUES ('No blanks', 'No blanks', 0x00ee)
INSERT INTO t2 VALUES ('Trailing blank ', 'Trailing blank ', 0x00ee00)

SELECT 'CHAR'='>' + charcol + '<', 'VARCHAR'='>' + varcharcol + '<',
varbinarycol
FROM t2
GO

DROP TABLE t1
DROP TABLE t2
GO

|||

Thanks for your info.

I had test your script, it work.

<<<BUT>>>.......

I find this "SET ANSI_NULLS ON" is not work if the COULMN defined as NOT NULL.

Here is my original script for table [CUSTOMER_CREDIT]

===============================================

USE DBSYSTEM
GO
SET ANSI_PADDING ON
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [MAIN].[CUSTOMER_CREDIT]
(
[CREDITOR_ID] varchar(10) NOT NULL,
[CREDIT_ID] varchar(6) NOT NULL,
[CREDIT_LIMIT] numeric(12, 2) NULL,
[CREDIT_BALANCE] numeric(12, 2) NULL,
[CREDIT_ONHAND] numeric(12, 2) NULL,
[ACCTSTATUSID] varchar(3) NULL,
[CREDITTERMSID] varchar(3) NULL,
[EDIT_TIME] datetime NULL
)
GO
ALTER TABLE [MAIN].[CUSTOMER_CREDIT]
ADD CONSTRAINT [PK_CUSTOMER_CREDIT]
PRIMARY KEY
CLUSTERED ([CREDITOR_ID] ASC, [CREDIT_ID] ASC)

GO

If I had create the table like this:

CREATE TABLE [MAIN].[CUSTOMER_CREDIT]
(
[CREDITOR_ID] varchar(10) NULL,
[CREDIT_ID] varchar(6) NOT NULL,
.....

If the COULMN [CREDITOR_ID] defined as NULL, "SET ANSI_PADDING ON" is work, such that I have two records:

[CREDITOR_ID] = 'ABCD ' , ie space after string "ABCD".

[CREDITOR_ID] = 'ABCD' , ie no space after string "ABCD".

But if the COULMN [CREDITOR_ID] defined as "NOT NULL", "SET ANSI_PADDING ON" is NOT work.

Any ideal?

|||

Here is the script to create table and testing:

USE DBSYSTEM
GO
SET ANSI_PADDING ON
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[MAIN].[CUSTOMER_CREDIT]') AND type in (N'U'))
BEGIN

DECLARE @.drop_statement varchar(500)

DECLARE drop_cursor CURSOR FOR
SELECT 'alter table '+quotename(schema_name(ob.schema_id))+
'.'+quotename(object_name(ob.object_id))+ ' drop constraint ' + quotename(fk.name)
FROM sys.objects ob INNER JOIN sys.foreign_keys fk ON fk.parent_object_id = ob.object_id
WHERE fk.referenced_object_id = OBJECT_ID(N'[MAIN].[CUSTOMER_CREDIT]')

OPEN drop_cursor

FETCH NEXT FROM drop_cursor
INTO @.drop_statement

WHILE @.@.FETCH_STATUS = 0
BEGIN
EXEC (@.drop_statement)

FETCH NEXT FROM drop_cursor
INTO @.drop_statement
END

CLOSE drop_cursor
DEALLOCATE drop_cursor

DROP TABLE [MAIN].[CUSTOMER_CREDIT]
END
GO

USE DBSYSTEM
GO
SET ANSI_PADDING ON
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE
[MAIN].[CUSTOMER_CREDIT]
(
[CREDITOR_ID] varchar(10) NOT NULL,
[CREDIT_ID] varchar(6) NOT NULL,
[CREDIT_LIMIT] numeric(12, 2) NULL,
[CREDIT_BALANCE] numeric(12, 2) NULL,
[CREDIT_ONHAND] numeric(12, 2) NULL,
[ACCTSTATUSID] varchar(3) NULL,
[CREDITTERMSID] varchar(3) NULL,
[EDIT_TIME] datetime NULL
)
GO
ALTER TABLE [MAIN].[CUSTOMER_CREDIT]
ADD CONSTRAINT [PK_CUSTOMER_CREDIT]
PRIMARY KEY
CLUSTERED ([CREDITOR_ID] ASC, [CREDIT_ID] ASC)

GO
===============================================================

SET ANSI_PADDING ON

GO

INSERT INTO [MAIN].[CUSTOMER_CREDIT] VALUES ('YT4996', 'XX','2400','0','0','C','30',CURRENT_TIMESTAMP)

GO

SET ANSI_PADDING ON

GO

INSERT INTO [MAIN].[CUSTOMER_CREDIT] VALUES ('YT4996 ','XX','0' ,'0','0','S','15',CURRENT_TIMESTAMP)

GO

SELECT 'VARCHAR'='>' + CREDITOR_ID + '<' FROM [MAIN].[CUSTOMER_CREDIT]
GO


Sunday, March 11, 2012

"OR" Condition in MDX?

Hi!

I'm new to MDX and have a simple problem with apparently no simple solution in MDX word, according to discussions, e.g. http://groups.google.com/group/microsoft.public.sqlserver.olap/browse_thread/thread/25ea010035f3f097/8ab30ca61c23bbfd%238ab30ca61c23bbfd

Is it possible to get records from OLAP cube, using OR condition to members of different dimensions? Below is an abstract example using [Adventure Works]:

select
non empty {[Measures].[Reseller Sales Amount]} on columns,
non empty { [Employee].[Employee].AllMembers
* [Product].[Product Line].AllMembers } on rows
from [Adventure Works]
where
[Geography].[Country].&[Canada]
OR SOMEHOW
[Reseller].[Reseller Type].[Business Type].&[Specialty Bike Shop]

Records should be returned if either country is Canada OR Business Type is Bike Shop. It's trivial with regular SQL, but seems to be very tricky with MDX. There may be more than 2 parameters.
It is easy to implement OR condition if parameters belong to the same dimension. But how if they are different?

Thanks!
Andy.

It is easy to do as well. Depending on how calculations are inside the cube it might be done in couple of different ways, but below is probably what most people would write here.

select

non empty {[Measures].[Reseller Sales Amount]} on columns,

non empty { [Employee].[Employee].AllMembers

* [Product].[Product Line].AllMembers } on rows

from [Adventure Works]

where

{([Geography].[Country].&[Canada], [Reseller].[Reseller Type].[Business Type].MEMBERS),

([Geography].[Country].MEMBERS,[Reseller].[Reseller Type].[Business Type].&[Specialty Bike Shop])}