NHibernate Profiler is lying to me? - nhibernate

Im using Fluent NHibernate as my ORM and NH Profiler is throwing me this sql query when I execute it
INSERT INTO [Location]
(Name,
Lat,
Lon)
VALUES ('my address' /* #p0 */,
-58.37538459999996 /* #p1 */,
-34.5969468 /* #p2 */);
which is absolutly correct by the way.
This is the design of my Location table:
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](255) NULL,
[Lat] [decimal](23, 20) NULL,
[Lon] [decimal](23, 20) NULL,
But when I see the inserted data in sqlserver management studio, I can see it inserted
-58.37538000000000000000 instead of -58.37538459999996000000 and
-34.59694000000000000000 instead of -34.59694680000000000000.
When I execute this insert query manually, it inserts the values correctly (the 14 decimals for Lat Column) , but if nhibernate does this, it only inserts 5 decimals.
Any ideas???

The issue comes with the default precision and scale. NHibernate default decimal representation is decimal (28,5), so that's why the final INSERT statement contains only 5 decimal places. XML mapping
<property name="Lat" precision="23" scale="20" />
<property name="Lon" precision="23" scale="20" />
fluent:
...
.Precision(23)
.Scale(20)
Now the INSERT statement will be decimal (23,20).

Related

Insert into multiple tables at once along with additional records

I have 2 tables
CREATE TABLE [dbo].[extendable1](
[serialnumber] [int] IDENTITY(1,1) NOT NULL,
[createdby] [nvarchar](36) NOT NULL,
[createddate] [datetime] NOT NULL)
CREATE TABLE [dbo].[extendable1_custom](
[serialnumber] [int] NOT NULL,
[createdby] [nvarchar](36) NOT NULL,
[createddate] [datetime] NOT NULL,
[currencyid] [nvarchar](3) NULL,
[partid] [nvarchar](30) NULL,
[price] [float] NULL)
I need to insert the same values into both tables at the same time for the columns with the same attributes along with additional data to the custom table, however I can't find any examples online to show me how this can be done, I have seen examples using the output clause and have attempted it going down this line to no success.
Just to point out my goal is to extract the indentity ID created in extendable1 and input this value to extendable1_custom
EDIT
An example of values I would like to insert:
insert into extendable1 (createdby, createddate) select 'SO', getDate()
Excluding serialnumber as its an IDENTITY field, these values will be the same in extendable 1 no matter how many records entered
insert into extendable1_custom (createdby, createddate, currencyid, partid, price) select (extendable1.serialnumber, extendable1.createdby, extendable1.createddate, #temp.currencyid, #temp.partid, #temp.price) from #temp
Is there another route I should be going or is this possible?
Thanks
you can insert into both tables at the same time using below query
START TRANSACTION;
INSERT INTO extendable1 VALUES (column1, column2, ..);
INSERT INTO extendable1_custom VALUES(column1, column2, columnx ..);
COMMIT;
You can't insert same records in one statement, but you can in one transaction as follows:
BEGIN TRAN
INSERT INTO [dbo].[extendable1] VALUES(.....)
INSERT INTO [dbo].[extendable1_custom] (serialnumber,createdby,createddate) VALUES(...,...,...)
COMMIT
This means that this chunk of code will be executed in its entirety (all or nothing) - you can read about Atomicity, which is one of the four characteristics of transactions.
Yes,you can simply use a begin tran and commit with the both statement.
Secondly you need to use the error handling along with the same.
And using a rollback if the tran count is above 0 in that case rollback the query.
Although Tran work as a same either all will get commit or none.But sometimes we encounter issue of insertion so for best possible result use rollback also.

MS SQL explicitly using "default defaults" on NOT NULL fields - why?

I stumbled upon this definition:
CREATE TABLE dbo.whatever (
[flBlahBlah] BIT DEFAULT ((0)) NOT NULL,
[txCity] NVARCHAR (50) DEFAULT ('') NOT NULL,
[cdFrom] VARCHAR (10) DEFAULT ('') NOT NULL
);
I can't think of a reason to add those default values. Not null string is defaulted to '' and bit is defaulted to 0. Is there a reason for defining these default values? Am I missing something? Is this in some best practice handbook I'm not aware of?
I'd just use:
CREATE TABLE dbo.whatever (
[flBlahBlah] BIT NOT NULL,
[txCity] NVARCHAR (50) NOT NULL,
[cdFrom] VARCHAR (10) NOT NULL
);
The database is in MS SQL Server 2012, now migrating to Azure Database.
For example you create table from a first batch of your question. Then insert value like this
INSERT INTO dbo.whatever (flBlahBlah) VALUES (1)
You will get 1 row dbo.whatever
flBlahBlah txCity cdFrom
1
So if you "forget" to insert in one of the column with default values determined - SQL Server will take care of them.
It is very useful when you got table, in which you need to insert new field. With default value determined you don't need to change SP/query's/other stuff that works with this table.

SQL Insert - String or binary data would be truncated for INT values

I'm getting the "String or binary data would be truncated" error when trying to insert integers to one of my tables.
I've read several post about the length of the column vs the length of the value one is inserting, but it doesn't seem to be my case once the columns are all int or smallint type and the values are all maximum two digits.
The table structure is the following:
CREATE TABLE [tblvUserLocation] (
[User_Location_ID] [int] IDENTITY (1, 1) NOT NULL ,
[Location_ID] [int] NULL ,
[Line_Type_ID] [int] NULL ,
[User_ID] [int] NULL ,
[Active] [smallint] NULL CONSTRAINT [DF_tblvUserLocation_Active] DEFAULT (1),
[Last_Updated] [smalldatetime] NULL CONSTRAINT [DF_tblvUserLocation_Last_Updated] DEFAULT (getdate()),
[Last_Updated_By] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL CONSTRAINT [DF_tblvUserLocation_Last_Updated_By] DEFAULT (suser_sname())
) ON [PRIMARY]
GO
The insert I'm trying to run is the following:
insert into tblvUserLocation (Location_ID, Line_Type_ID, [User_ID], Active)
values (20, 2, 41, 1)
And the error I'm getting is the following:
Server: Msg 8152, Level 16, State 2, Line 1 String or binary data
would be truncated. The statement has been terminated.
If that makes any difference, I'm using SQL Server 2000.
Please let me know what your thoughts are.
Thanks!
Looks like the problem comes from your [DF_tblvUserLocation_Last_Updated_By] constraint.
It's pulling the current username which is more than likely longer than the length of your [Last_Updated_By] column VARCHAR(10).
Update your DDL to:
[Last_Updated_By] [varchar] (128)

Error Creating Database Diagram in SSMS 2012

When I attempt to create a database diagram, I get the following error:
Cannot insert the value NULL into column 'diagram_id', table 'MyDB.dbo.sysdiagrams'; column does
not allow nulls. INSERT fails.
The statement has been terminated.
The 'sp_creatediagram' procedure attempted to return a status of NULL, which is not allowed. A status of
0 will be returned instead. (.Net SqlClient Data Provider)
I am using SSMS 2012.
The database is set at a compatibility level of SQL Server 2012 (110)
##Version is Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
Your problem is the diagram_ID when the table was created probably looked something like this
CREATE TABLE <table_name>
( diagram_ID INT NOT NULL PRIMARY KEY,
n...,
)
This basically means that a NULL value cannot be inserted into that column because of the NOT NULL condition. So an insert statement like:
INSERT INTO <table_name>
(Diagram_ID, n...,)
VALUES
(NULL, n...,)
Would fail because of the NULL you would need to have a value in there like (since I called it an integer):
INSERT INTO <table_name>
(Diagram_ID, n...,)
VALUES
(23, n...,)
The column may also be an indentity column in which case you have no controll over what can be inserted into the table.
Go to system tables and look for systemdiagrams table, and turn to YES the "indentity Specification" property for the field diagram_id
Hope this will help you, this script solved my issues
DROP TABLE dbo.sysdiagrams;
GO
CREATE TABLE [dbo].[sysdiagrams]
(
[name] [sysname] NOT NULL,
[principal_id] [int] NOT NULL,
[diagram_id] [int] IDENTITY(1,1) PRIMARY KEY,
[version] [int] NULL,
[definition] [varbinary](max) NULL,
CONSTRAINT [UK_principal_name] UNIQUE ([principal_id],[name])
);
GO
EXEC sys.sp_addextendedproperty
#name=N'microsoft_database_tools_support',
#value=1 ,
#level0type=N'SCHEMA',
#level0name=N'dbo',
#level1type=N'TABLE',
#level1name=N'sysdiagrams';
GO

Triggering a timestamp update

For every INSERT, how do I populate my DateStamp field with the current datetime?
I've created an error output table for my SSIS task:
Here's the table:
CREATE TABLE [dbo].[gbs_CRMErrorOutput](
[ID] [uniqueidentifier] NULL,
[ErrorCode] [nvarchar](50) NULL,
[ErrorColumn] [nvarchar](500) NULL,
[CrmErrorMessage] [nvarchar](max) NULL,
[targetid] [uniqueidentifier] NULL,
[subordinateid] [uniqueidentifier] NULL,
[DateStamp] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Please note that I do not have an auto-increment or any key in the table.
I'm also wondering what would be a best practice for this?
Here is an example of using not null with a default. In your real table you may want to name your default constraint. If you define the constraint inline like this it will still be named but it will be automatically assigned.
CREATE TABLE #MyTable
(
MyID INT IDENTITY NOT NULL,
SomeValue VARCHAR(10),
DateCreated DATETIME NOT NULL DEFAULT GETDATE()
)
INSERT #MyTable(SomeValue)
VALUES ('Value1')
--This next line just waits for 1 second.
--This will demonstrate multiple inserts at different times so you can the values change
WAITFOR DELAY '00:0:01'
INSERT #MyTable(SomeValue)
VALUES ('Value2')
SELECT *
FROM #MyTable
DROP TABLE #MyTable
Two good options:
1) Create a DEFAULT CONSTRAINT on your table with GETDATE() specified for your column (good example here). Within SSIS, do not map any value to that column - leave it as Ignore. Make sure that Keep Nulls is not checked. Note that you might have to fiddle with the settings of your OLE DB Destination - uncheck Identity Insert if there's a problem. I've also seen cases where the column had to allow NULLs - that only affects certain scenarios.
2) Add a Derived Column transformation to your data flow, setting it up to add a new column to the flow. I usually use the System::StartTime variable here, so that all records inserted during a single ETL run will share the same inserted date, but you could just as easily use the SSIS function GETDATE().
Map the new column you just created to your OLE DB Destination.