Storing XML file in SQL Server 2008 R2 express - c#

I am trying to store XML data into a SQL Server 2008 R2 Express database, every xml file has different data. What is the easiest way to do this?
What are the best options please explain with example.

I believe easiest way will be to create a stored procedure to handle the storage for you. You can then retrieve it by an ORM of preferage and let C# deserialize it for you.
CREATE TABLE [dbo].[MyXmlStorage]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[FileName] [nvarchar](255) NOT NULL,
[Xml] [xml] NOT NULL,
CONSTRAINT [PK_MyXmlStorage]
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE PROCEDURE [dbo].[InsertXml]
(#filePathFull nvarchar(255))
AS
DECLARE #xmlAsString VARCHAR(MAX)
DECLARE #sql nvarchar(max)
DECLARE #xml XML
DECLARE #Rms_FileId nvarchar(50)
DECLARE #Rms_Id nvarchar(50)
DECLARE #Rms_Type nvarchar(50)
DECLARE #Rms_Timestamp nvarchar(50)
BEGIN
SET #sql = 'SELECT #xmlAsString = x.y FROM OPENROWSET( BULK ''' + RTRIM(#filePathFull) + ''', SINGLE_CLOB) x(y)'
exec sp_executesql #sql,N'#xmlAsString VARCHAR(MAX) OUTPUT',#xmlAsString OUTPUT
set #xml = CONVERT(XML,#xmlAsString)
INSERT INTO MyXmlStorage([FileName],[Xml])
VALUES (#filePathFull, #xml)
END
Then run it like this:
exec InsertXml N'C:\files\xmlfile.xml'

Ok, this is an example for storing the values of the xml into the table instead. I havent't tried this code but it should be working but at least it should clarify how to do as expected.
/* Imagine your xml looks something like this
<Content>
<Title>Text</Title>
<Value>15</Value>
</Content>
*/
CREATE TABLE [dbo].[MyXmlStorage]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Value] int NOT NULL,
CONSTRAINT [PK_MyXmlStorage]
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE PROCEDURE [dbo].[InsertXml]
(#filePathFull nvarchar(255))
AS
DECLARE #xmlAsString VARCHAR(MAX)
DECLARE #sql nvarchar(max)
DECLARE #xml XML
DECLARE #Rms_FileId nvarchar(50)
DECLARE #Rms_Id nvarchar(50)
DECLARE #Rms_Type nvarchar(50)
DECLARE #Rms_Timestamp nvarchar(50)
BEGIN
SET #sql = 'SELECT #xmlAsString = x.y FROM OPENROWSET( BULK ''' + RTRIM(#filePathFull) + ''', SINGLE_CLOB) x(y)'
exec sp_executesql #sql,N'#xmlAsString VARCHAR(MAX) OUTPUT',#xmlAsString OUTPUT
set #xml = CONVERT(XML,#xmlAsString)
/* Use xpath to query nodes for values inside the Content tag*/
INSERT INTO MyXmlStorage([Title],[Value])
SELECT
x.y.value('title[1]/text()[1]', 'nvarchar(100)') AS title,
x.y.value('value[1]/text()[1]', 'int') AS value
FROM #xml.nodes('//Content') AS x(y)
END
)

Related

How do I check that values are being inserted into a table when the result of the insert shows nothing?

I've ran into an issue concerning a SQL Server procedure that is supposed to insert data into three tables. The code below shows that the procedure takes in parameters and then inserts said parameters into three tables: an Address table, a D.O.B table and a Users table.
Ignoring the salt as that has to do with something else, my issue is that when I run this procedure from an ASP.NET MVC file, nothing is inserted into the Users table, even though the Address and D.O.B table both have their respective values inserted into them. I've had an issue like this before which was solved because the problem was that one of the values was returning NULL when I used a HASHBYTES procedure on it, however, here there is nothing that I can think that would be doing something similar.
ALTER PROCEDURE [dbo].[StoreDetails]
#FirstName VARCHAR(50),
#Surname VARCHAR(50),
#Password VARCHAR(100),
#PhoneNumber VARCHAR(50),
#Email VARCHAR(100),
#IsAdmin BIT,
#Address VARCHAR(100),
#DOB DATE
AS
BEGIN
SET NOCOUNT ON
DECLARE #Salt UNIQUEIDENTIFIER = NEWID()
INSERT INTO dbo.OAddress(Address)
VALUES (#Address)
INSERT INTO dbo.ODOB(DOB)
VALUES (#DOB)
INSERT INTO dbo.OUsers (FirstName, Surname, Password, Salt, PhoneNumber, Email, IsAdmin, AddressID, DOBID)
VALUES (#FirstName, #Surname, #Password, #Salt, #PhoneNumber, #Email, #IsAdmin, SCOPE_IDENTITY(), SCOPE_IDENTITY())
END
The C# side of this I believe does work as intended as not too long ago I managed to get this code to work until I changed the stored procedure to try and change the Password parameter to get hashed using HASHBYTES however I decided to just revert back to when it worked normally but as you can see I'm failing.
Seems like what you likely need is a couple of OUTPUT clauses and some table variables:
ALTER PROCEDURE [dbo].[StoreDetails] #FirstName varchar(50),
#Surname varchar(50),
#Password varchar(100),
#PhoneNumber varchar(50),
#Email varchar(100),
#IsAdmin bit,
#Address varchar(100),
#DOB date
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Salt uniqueidentifier = NEWID();
DECLARE #AddressID table (ID int);
DECLARE #DOBID table (ID int);
INSERT INTO dbo.OAddress ([Address])
OUTPUT inserted.ID
INTO #AddressID (ID) --Guessed named for inserted
SELECT #Address;
INSERT INTO dbo.ODOB (DOB)
OUTPUT inserted.ID
INTO #DOBID (ID) --Guessed named for inserted
SELECT #DOB;
INSERT INTO dbo.OUsers (FirstName,
Surname,
Password,
Salt,
PhoneNumber,
Email,
IsAdmin,
AddressID,
DOBID)
SELECT #FirstName,
#Surname,
#Password,
#Salt,
#PhoneNumber,
#Email,
#IsAdmin,
A.ID,
D.ID
FROM #AddressID A
CROSS JOIN #DOBID D;
END;
Note the comments I make on the OUTPUT clauses.
You need to figure out what the database is telling you about the problem.
Put a breakpoint in your code and then grab all the values that the variables contain that you are putting into your parameters. Then switch to SQL, set up all your variables, and try running the statements from the procedure, and get the error message. Something like this:
declare #FirstName VARCHAR(50) = 'John'
declare #Surname VARCHAR(50) = 'Smith'
declare #Password VARCHAR(100) = 'Hek3$s*aSf8'
declare #PhoneNumber VARCHAR(50) = '333-333-3333'
declare #Email VARCHAR(100) = 'john#mailinator.com'
declare #IsAdmin BIT = 0
declare #Address VARCHAR(100) = '100 Somewhere Street, Somewheretown'
declare #DOB date = '2019-10-10'
DECLARE #Salt UNIQUEIDENTIFIER=NEWID()
INSERT INTO dbo.OAddress(Address)
VALUES(#Address)
INSERT INTO dbo.ODOB(DOB)
VALUES(#DOB)
INSERT INTO dbo.OUsers(FirstName,Surname,Password,Salt,PhoneNumber,Email,IsAdmin,AddressID,DOBID)
VALUES(#FirstName,#Surname,#Password,#Salt,#PhoneNumber,#Email,#IsAdmin,SCOPE_IDENTITY(),SCOPE_IDENTITY())
I think we probably need to suspect the SCOPE_IDENTITY() function calls, but there's only one way to find out: run it and see.
The problem here is the use of SCOPE_IDENTITY(). This returns the last identity value generated by the insert statement. In your code, SCOPE_IDENTITY() is returning the value inserted for dbo.oDOB.
In order for this to work, you would need to capture the value for SCOPE_IDENTITY() into a local variable after each of the insert statements, then use those values in your final insert into dbo.oUsers.
The following should get you what you want:
ALTER PROCEDURE [dbo].[StoreDetails]
#FirstName VARCHAR(50),
#Surname VARCHAR(50),
#Password VARCHAR(100),
#PhoneNumber VARCHAR(50),
#Email VARCHAR(100),
#IsAdmin BIT,
#Address VARCHAR(100),
#DOB DATE
AS
BEGIN
SET NOCOUNT ON
DECLARE #addressKey INT,
#dobKey INT;
DECLARE #Salt UNIQUEIDENTIFIER = NEWID();
INSERT INTO dbo.OAddress(Address)
VALUES (#Address);
SET #addressKey = SCOPE_IDENTITY();
INSERT INTO dbo.ODOB(DOB)
VALUES (#DOB);
SET #dobKey = SCOPE_IDENTITY();
INSERT INTO dbo.OUsers (FirstName, Surname, Password, Salt, PhoneNumber, Email, IsAdmin, AddressID, DOBID)
VALUES (#FirstName, #Surname, #Password, #Salt, #PhoneNumber, #Email, #IsAdmin, #addressKey, #dobKey)
END
Firstly, you should run stored procedure with the params to know what are error messages exactly.
Secondly, You should handle error message inner stored procedure and check after each time you inserted.
For example:
INSERT INTO dbo.OAddress(Address)
VALUES(#Address)
IF ##ERROR <> 0
BEGIN
PRINT N'A check constraint violation occurred.';
Return;
END
GO
However, You should also use out put param then RETURN ##ERROR to check in c# whether it's inserted successfully or not

Two entities mapped to a single stored procedure in Entity Framework: DB First Approach

I have 2 tables in the DB, namely Students and Class.
I have created a single stored procedure, namely Update, to update both the tables.
I have created a WebForms project and have added an Entity Data Model via Database First approach. Now how do I map the procedure to both the entities?
The entities are not related to each other by any means.
Below is my stored proc and the table skeletons:
ALTER Procedure [dbo].[UpdateStudent]
#Id int,
#Name varchar(20),
#City varchar(20),
#ClassId int,
#ClassName varchar(10),
#ClassLocation varchar(10)
as
begin
update Students set Name=#Name, City=#City where Id=#Id
update Class set ClassName=#ClassName, ClassLocation=#ClassLocation where ClassId=#ClassId
end
GO
CREATE TABLE [dbo].[Class](
[ClassID] [int] IDENTITY(1,1) NOT NULL,
[ClassName] [varchar](10) NULL,
[ClassLocation] [varchar](10) NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Students](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](20) NULL,
[City] [varchar](20) NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Below is my EDMX file:
Please advise.
Regards

Stored Procedure Storing 0 in Auto increment column in Table

I have the following table where ProspectCode is Identity Not Null
Table LeadMastersNew
ProspectCode int
CompanyName nvarchar(50)
PersonName nvarchar(50)
Designation nvarchar(50)
Number nvarchar(50)
Number2 nvarchar(50)
Emailaddress nvarchar(50)
Address nvarchar(MAX)
Address2 nvarchar(MAX)
CityName nvarchar(50)
State nvarchar(50)
PinNumber nvarchar(50)
Product nvarchar(50)
RemarkNote nvarchar(MAX)
The issue which I am facing lately is that when I am storing records to the above table using stored procedure,ProspectCode is always set to 0 for all the rows that I add.I have 160 Records in the above table,But when I add new Record, its ProspectCode is set to 0 for all the record that I add.
Stored Procedure
ALTER Procedure [dbo].[Proc_InsertLeads]
#ProspectCode nvarchar(50),#CompanyName nvarchar(50),#PersonName nvarchar(50),#Designation nvarchar(50),#Number nvarchar(50),
#Number2 nvarchar(50),#Emailaddress nvarchar(50),#Address nvarchar(MAX),#Address2 nvarchar(MAX),
#CityName nvarchar(50),#State nvarchar(50),#PinNumber nvarchar(50),#Product nvarchar(50),#RemarkNote nvarchar(MAX)
AS
BEGIN
SET IDENTITY_INSERT LeadMastersNew ON;
INSERT INTO LeadMastersNew
(ProspectCode,CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote)
VALUES(#ProspectCode,#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote)
INSERT INTO LoggerLeadMasters
(ProspectCode,CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote,Activity,ActivityTime)
VALUES(#ProspectCode,#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote,'New Record Added',getdate())
SET IDENTITY_INSERT LeadMastersNew OFF;
END
EXEC Proc_InsertLeads'ABc','Mr abc','MD','PhoneNumber','','abc#abcindia.com','xyz','','Mumbai','Maharashtra','400059','Abc', 'Abc'
Sets ProspectCode to 0
Can anyone help me to fix this issue? Do I have to change my stored Procedure or Table Schema?
Thanks
If you want an identity column to assign numbers automatically, the thing you really shouldn't be doing is setting IDENTITY_INSERT to ON. Turning that setting on says to SQL Server "trust me, I'll provide the values in the identity column".
You probably want code something like:
BEGIN
DECLARE #NewID int
INSERT INTO LeadMastersNew
(/*ProspectCode,*/CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote)
VALUES(/*#ProspectCode,*/#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote)
SET #NewID = SCOPE_IDENTITY()
INSERT INTO LoggerLeadMasters
(ProspectCode,CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote,Activity,ActivityTime)
VALUES(#NewID ,#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote,'New Record Added',getdate())
END
This may not work exactly first time since I can't reconcile the code you've shown with how you're calling it. If ProspectCode is indeed an int column and you're actually trying to insert an nvarchar value of 'Choice Brokers', you should be getting an error.
you don't need identity_insert if you set autoincrement
remove rows
SET IDENTITY_INSERT LeadMastersNew ON;
SET IDENTITY_INSERT LeadMastersNew OFF;
and it should work
Here ProspectCode must set to Auto-increment since it is identity column for table. So basically in store procedure you must remove input parameter #ProspectCode and while inserting new row don't ON OFF IDENTITY_INSERT on table, final store procedure look like:
ALTER Procedure [dbo].[Proc_InsertLeads]
#CompanyName nvarchar(50),#PersonName nvarchar(50),#Designation nvarchar(50),#Number nvarchar(50),
#Number2 nvarchar(50),#Emailaddress nvarchar(50),#Address nvarchar(MAX),#Address2 nvarchar(MAX),
#CityName nvarchar(50),#State nvarchar(50),#PinNumber nvarchar(50),#Product nvarchar(50),#RemarkNote nvarchar(MAX)
AS
BEGIN
DECALRE #ID INT = 0
INSERT INTO LeadMastersNew
(CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote)
VALUES(#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote)
SET #ID = SCOPE_IDENTITY()
INSERT INTO LoggerLeadMasters
(ProspectCode,CompanyName,PersonName,Designation,Number,Number2,Emailaddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote,Activity,ActivityTime)
VALUES(#ID,#CompanyName,#PersonName,#Designation,#Number,#Number2,#Emailaddress,#Address,#Address2,#CityName,#State,#PinNumber,#Product,#RemarkNote,'New Record Added',getdate())
END
Here I am using #ID parameter to find newly inserted ProspectCode in table LeadMastersNew which will used in table LoggerLeadMasters as ProspectCode.

Error in Function EF

i use Entity Framework + SQl 2008 + .Net Framework 4 + SP in SQL.
and crate Function in EF for Insert value into sql.
fro EX:
Function Import Name: InsertStudent
stroed Procedure Name: InsertStudent
Returns a Collection Of: Scalars: Int32
SP:
create proc InsertStudent
(
#DateReg datetime,
#stdLastName nvarchar(50),
#stdFirstName nvarchar(50),
#Description nvarchar(500)
)
INSERT INTO Student(DateReg,stdLastName,stdFirstName,[Description])
VALUES (#DateReg,#stdLastName,#stdFirstName,#Description)
the Date Saving at SQL but Error in Function EF:
The data reader returned by the store data provider does not have enough columns for the query requested.
i think you need to insert primary key value for through sp.
create proc InsertStudent
(
#stdID int,
#DateReg datetime,
#stdLastName nvarchar(50),
#stdFirstName nvarchar(50),
#Description nvarchar(500)
)
INSERT INTO Student(stdID,DateReg,stdLastName,stdFirstName,[Description])
VALUES (#stdID,#DateReg,#stdLastName,#stdFirstName,#Description)

SQL Server VARBINARY(MAX)

I have a stored procedure that inserts a varchar & VARBINARY(MAX) values in the table.
I pass a c# byte[] to the varbinary(max) field. I also see that the size of the byte[] size is 80142 which satisfies the max limit of varbinary. Stored procedure executes without any errors. But when I try to query that table I see empty values in the varbinary datatype.
SQL sp
ALTER PROCEDURE [dbo].[Test]
-- Add the parameters for the stored procedure here
#PNumber varchar(50)
,#Byte varbinary(max)
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO [Test].[dbo].[Data]
([PNumber]
,[PByte])
VALUES
(#PNumber
,#Byte)
END
C# CODE
byte[] theData = doc.GetData();
DAL_DataTableAdapters.QueriesTableAdapter qta = new DAL_DataTableAdapters.QueriesTableAdapter();
qta.Test("test", theData);
Table structure:
CREATE TABLE [dbo].[Data]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[PNumber] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[PByte] [varbinary](max) NULL
) ON [PRIMARY]
How do you determine that the data is empty? I'm quite certain that SQL Server Management Studio will not display a value that is too long (I don't know the limit), even when the value is there.

Categories