I have an Stored Procedure in SQL Server 2012:
CREATE procedure [dbo].[GetEmailThread]
(
#id int
)
AS
SELECT e.Id, e.Created, e.MailFrom, e.MailTo, e.Body, e.Sended, ip.Ip, e2.Sended as ReplySended, e2.Body as ReplyBody, e2.Id as ReplyId
FROM Emails e
LEFT JOIN IpAddress ip ON (ip.Id = e.IpId)
LEFT JOIN Emails e2 ON (e.Id = e2.ParentEmailId)
WHERE e.RealtyId = #id
ORDER BY e.Sended, ReplySended
Definition of Email Table:
CREATE TABLE [dbo].[Emails](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Created] [datetime] NOT NULL,
[MailFrom] [nvarchar](100) NOT NULL,
[MailTo] [nvarchar](500) NOT NULL,
[Subject] [nvarchar](500) NULL,
[Body] [nvarchar](max) NULL,
[Sended] [datetime] NULL,
[Ip] [varchar](15) NULL,
[ReplyTo] [nvarchar](100) NULL,
[IpId] [int] NULL,
[RealtyId] [int] NULL,
[ParentEmailId] [int] NULL,
[IsBodyHtml] [bit] NOT NULL CONSTRAINT [DF_Emails_IsBodyHtml] DEFAULT ((0)),
And EntityFramework model in C#. Whenever I right-click in Visual Studio Model Browser to this EntityFramework model and choose the menu "Update Model from Database", the model gets updated, but the field MailTo in GetEmailThread_Result is always missing.
I need to add it manually to the model GetEmailThread_Result.cs to get it working.
Why? Why this? I cannot see anything special in this field. Why not MailFrom?
The solution was to manually edit EF files in the project as they were corrupted, for details see Updating Entity Framework Model
Related
I used Dapper ExecuteAsync method to execute a SQL query with params.
insertedId =await connection.ExecuteAsync(query,params, transaction);
But this error occurs:
"Column name or number of supplied values does not match table
definition."
The Good table definition:
[Id] [int] IDENTITY(1,1) NOT NULL,
[Code] [nvarchar](50) NULL,
[Title] [nvarchar](200) NOT NULL,
[GoodEnumId] [int] NOT NULL,
[Date] [datetime] NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDeleted] [bit] NOT NULL,
And the PaperDetail table definition:
[Id] [int] IDENTITY(1,1) NOT NULL,
[GoodId] [int] NOT NULL,
[Length] [float] NULL,
[Width] [float] NULL,
[Grammage] [float] NULL,
[Date] [datetime] NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDeleted] [bit] NOT NULL,
This is the query:
declare #Good1Scalar int
create table #Good1 (Id int)
insert into [Good] (Code, Title, GoodEnumId, Date, IsActive, IsDeleted)
output inserted.Id into #Good1
values (#Param2, #Param3, #Param4, #Param5, #Param6, #Param7)
SELECT #Good1Scalar = id from #Good1
drop table #Good1
insert into [PaperDetail](GoodId, Length, Width, Grammage, Date, IsActive, IsDeleted)
values (#Good1Scalar, #Param8, #Param9, #Param10, #Param11, #Param12, #Param13)
And this is my params value and DbType object (of DynamicParameters type):
What's wrong?
Update:
Using SQL Server Profiler I get the final code and run it on the
SQL server management studio directly. The query has no error. So surely this error message is misleading and the problem is somewhere else.
For testing, I remove the transaction and the error disappeared. So
I noticed that the problem is from the transaction. That's why I
reviewed the previous method that takes this transaction (calling the QueryMultiple in one method).
I replaced the dapper QueryMultiple with a DataAdapter Fill method. and finally, the error disappeared.
It's still unclear from the question what is the type of param variable passed to Dapper's ExecuteAsync call. The preferred way of passing parameters is through DynamicParameters bag.
Here is the code that works with your table definitions and the query.
DynamicParameters parameters = new DynamicParameters();
parameters.Add("Param2", "TheCode");
parameters.Add("Param3", "TheTitle");
parameters.Add("Param4", 4);
parameters.Add("Param5", "2018-01-28");
parameters.Add("Param6", true);
parameters.Add("Param7", false);
parameters.Add("Param8", 300);
parameters.Add("Param9", 30);
parameters.Add("Param10", 3);
parameters.Add("Param11", "2018-01-28");
parameters.Add("Param12", true);
parameters.Add("Param13", true);
var insertedId = await connection.ExecuteAsync(query, parameters, transaction);
Give it a try, it should work.
Im using tableAdapters to insert values to a table.
Heres my table aaTest
CREATE TABLE [dbo].[aaTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[INVOICEDATE] [datetime2](0) NULL,
[CHARGEDATE] [datetime2](0) NULL,
[EZPASS] [varchar](50) NULL,
[PLAZA] [varchar](10) NULL,
[PLAZA2] [varchar](10) NULL,
[PDATE] [datetime2](0) NULL,
[PTIME] [varchar](9) NULL,
[PAMOUNT] [decimal](18, 2) NULL,
[PBALANCE] [decimal](18, 2) NULL,
[ACTION] [varchar](10) NULL
) ON [PRIMARY]
in my dataset, my initial fill command is select * from aatest, and ive created an insert query
INSERT INTO [aatest] ([INVOICEDATE], [CHARGEDATE], [EZPASS], [PLAZA], [PLAZA2], [PDATE], [PTIME], [PAMOUNT], [PBALANCE], [ACTION])
VALUES (#INVOICEDATE, #CHARGEDATE, #EZPASS, #PLAZA, #PLAZA2, #PDATE, #PTIME, #PAMOUNT, #PBALANCE, #ACTION)
now under my dataset designer, my query is being declared as such
public virtual int InsertQuery(string INVOICEDATE, string CHARGEDATE, string EZPASS, string PLAZA, string PLAZA2, string PDATE, string PTIME, global::System.Nullable<decimal> PAMOUNT, global::System.Nullable<decimal> PBALANCE, string ACTION)
the problem im having is, INVOICEDATE, CHARGEDATE and PDATE are being generated as strings when they are in fact datetime2. this causes the exception
The best overloaded method match for (mydataset) has some invalid arguments.
changing it to datetime worked temporary, but after a while they regenerated back to strings.
You need to change [datetime2] to just [datetime], that should fix your issue.
At one point, there was a Node entity that had a field Alias. However, things have changed, and now we have modified that data model so that a Node can have multiple Aliases, and therefore, a Node now support an array of Aliases (which in turn creates an Aliases table, and an AliasesNodes table that maps the many-to-many relationship).
My question is, how do I update my stored procedure so that it supports this, and how do I modify the c# code that calls this stored procedure?
The requirements from the procedure is to only insert a Node if it doesn't exists, for each Alias, only insert if it doesn't exist, and finally, create the relationships between the Node and its Aliases.
OLD working stored procedure when Alias was a field (before an Alias table existed):
CREATE TYPE [dbo].[NodeTableType] AS TABLE
(
[Id] [int] NOT NULL,
[NodeTypeId] [smallint] NOT NULL,
[Location] [nvarchar](50) NULL,
[DisplayName] [nvarchar](100) NULL,
[AccessLevel] [smallint] NOT NULL,
[IsEnabled] [bit] NOT NULL,
[CreatedOn] [datetime2](7) NULL,
[CreatedBy] [nvarchar](150) NULL,
[ModifiedOn] [datetime2](7) NULL,
[ModifiedBy] [nvarchar](150) NULL,
[NativeId] [bigint] NOT NULL,
[SourceId] [int] NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[Alias] [nvarchar](100) NULL
);
CREATE PROCEDURE [dbo].[InsertNonExistingNode]
(#TableVariable dbo.NodeTableType READONLY)
AS
BEGIN
INSERT INTO NWatchNodes WITH (ROWLOCK) (Id, NodeTypeId, Location, DisplayName,
AccessLevel, IsEnabled, CreatedOn, CreatedBy,
ModifiedOn, ModifiedBy, NativeId, SourceId, Name, Alias)
SELECT
t.Id, t.NodeTypeId, t.Location, t.DisplayName,
t.AccessLevel, t.IsEnabled, t.CreatedOn, t.CreatedBy,
t.ModifiedOn, t.ModifiedBy, t.NativeId, t.SourceId, t.Name, t.Alias
FROM
#TableVariable t
LEFT JOIN
NWatchNodes PR WITH (NOLOCK) ON PR.Id = t.Id
WHERE
PR.ID IS NULL
END;
I have two tables in SQLServer 2014, one with ~100M points and one with ~2000 polygons.
Each point intersects with only one of the polygons. The task is to assign the ID of the intersecting polygon to the point.
What is the best practice to do it?
I have tried it in C#, loading two datatables, going row by row through the points and row by row through the polygons to find matches.
Boolean inside = (Boolean)polygon.STIntersects(point);
This is painfully slow since i have to access each point separately and each polygon multiple times to check for intersection. Any ideas are very welcome!
Create table statement for Points
CREATE TABLE [dbo].[ManyPoints](
[idNearByTimeLine] [int] IDENTITY(1,1) NOT NULL,
[msgID] [bigint] NOT NULL,
[userID] [bigint] NULL,
[createdAT] [datetime2](0) NULL,
[WGSLatitudeX] [numeric](9, 6) NULL,
[WGSLongitudeY] [numeric](9, 6) NULL,
[location] [geography] NULL
)
and Polygons
CREATE TABLE [dbo].[ManyPolygons](
[OBJECTID] [int] IDENTITY(1,1) NOT NULL,
[Shape] [geography] NULL,
[ID_0] [int] NULL,
[ISO] [nvarchar](3) NULL,
[NAME_0] [nvarchar](75) NULL,
[ID_1] [int] NULL,
[NAME_1] [nvarchar](75) NULL,
[ID_2] [int] NULL,
[NAME_2] [nvarchar](75) NULL,
[ID_3] [int] NULL,
[NAME_3] [nvarchar](75) NULL,
[NL_NAME_3] [nvarchar](75) NULL,
[VARNAME_3] [nvarchar](100) NULL,
[TYPE_3] [nvarchar](50) NULL,
[ENGTYPE_3] [nvarchar](50) NULL,
[ORIG_FID] [int] NULL,
)
Both tables have a spatial index on "location" and "Shape"
Select idnearbytimeline, objectid
From dbo.manypoints as point
Join dbo.manypolygons as polygon
On point.location.STIntersects(polygon.shape) =1
I came up with another solution. This is a stored procedure which selects all points within a given polygon ID. Then I use a simple C# program to loop through all polygons. However this is still not optimal and painfully slow. Any tweaks that can be made easily?
USE [<<DATABASE>>]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[test] #ID INT
AS
SET IDENTITY_INSERT [weiboDEV].[dbo].[<<NEW TABLE>>] ON;
-- Select Points in Polygon (Geography)
DECLARE #Shape GEOGRAPHY = (select [Shape] from <<POLYGONS>> where OBJECTID=#ID);
DECLARE #SQLString2 NVARCHAR(500)= N'INSERT INTO <<NEW TABLE>>(<<YOUR COLUMNS>>) SELECT <<YOUR COLUMNS>> FROM <<POINTS>> WHERE ([location]).STWithin(#Shape) = 1;';
DECLARE #ParmDefinition NVARCHAR(500) = N'#ID INT, #Shape geography';
EXECUTE sp_executesql #SQLString2, #ParmDefinition, #ID, #Shape;
GO
I suggest you to store your points of single polygon with comma separated string. So it can be covered in only one record for each polygon.
It may be a simple/specific question but I really need help on that. I have two tables: Entry and Comment in a SQL Server database. I want to show comment count in entry table. And of course comment count will increase when a comment is added. Two tables are connected like this:
Comment.EntryId = Entry.Id
Entry table:
CREATE TABLE [dbo].[Entry] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Subject] NVARCHAR (MAX) NOT NULL,
[Content] NVARCHAR (MAX) NOT NULL,
[Type] NVARCHAR (50) NOT NULL,
[SenderId] NVARCHAR (50) NOT NULL,
[Date] DATE NOT NULL,
[Department] NVARCHAR (50) NULL,
[Faculty] NVARCHAR (50) NULL,
[ViewCount] INT DEFAULT ((0)) NOT NULL,
[SupportCount] INT DEFAULT ((0)) NOT NULL,
[CommentCount] INT DEFAULT ((0)) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
Comment table:
CREATE TABLE [dbo].[Comment] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[EntryId] INT NOT NULL,
[SenderId] NVARCHAR (50) NOT NULL,
[Date] DATETIME NOT NULL,
[Content] NVARCHAR (MAX) NOT NULL,
[SupportCount] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
I am showing the entries in a gridview in codebehind (c#). The question is this, what should I write as a query to do this most efficiently? Thanks for help.
Try this:
select e.Id,e.date,count(*) as NumComments
from Entry e
join comment c on c.entryId=e.id
group by e.id,e.date
If there might be no comments, try the following
select e.Id,e.date,count(c.entryId) as NumComments
from Entry e
left join comment c on c.entryId=e.id
group by e.id,e.date
You can use left join for that purpose. Kindly me more specific with what fields you want in gridview
And why do you want commentcount in table (most tables have that 1-many relation and we didn't use that). If you keep that in table you have to update entry table every time when comment is made.