SQL aspnet_profile - sql

any idea how I can get user FirstName and LastName from the aspnet_profile table based on UserID using SQL becasue I would like to use in Telerik Reporting as a user parameter.
Sample row (FirstName is George, LastName is Test):
UserID: 06b24b5c-9aa1-426e-b7e4-0771c5f85e85
PropertyName: MobilePhone:S:0:0:Initials:S:0:1:City:S:1:14:FirstName:S:15:6:PostalCode:S:21:7:‌​WorkPhone:S:28:12:LastName:S:40:5:Address1:S:45:17:Address2:S:62:0:Province:S:62:‌​2:Organization:S:64:4:ClinicId:S:68:1:Country:S:69:6:Fax:S:75:0:MSPNumber:S:75:0:‌​
PropertyValuesString: HEast HustonEASGeorgeT7D 1N8604-111-2222Test5555 Beddtvue AveDCHCNL2Canada
PropertyValuesBinary: <Binary data>
LastUpdateDate: 2010-01-02 22:22:03.947

If you insist on using SQL, I'm sure a large number of SUBSTRINGs and PATINDEXes will get you there but it won't be a clean solution.
Update: user373721 found a great resource and posted a comment about it, but it can be easily missed, so I decided to add it to the answer, too - How to get asp.net profile value from MS SQL database using T-SQL?
The built-in dbo.aspnet_Profile_GetProperties stored procedure returns the PropertyValuesString value that is later parsed in the ParseDataFromDB
function.
private void GetPropertyValuesFromDatabase(string userName, SettingsPropertyValueCollection svc)
{
if (HostingEnvironment.IsHosted && EtwTrace.IsTraceEnabled(4, 8))
{
EtwTrace.Trace(EtwTraceType.ETW_TYPE_PROFILE_BEGIN, HttpContext.Current.WorkerRequest);
}
HttpContext current = HttpContext.Current;
string[] names = null;
string values = null;
byte[] buffer = null;
if (current != null)
{
if (!current.Request.IsAuthenticated)
{
string anonymousID = current.Request.AnonymousID;
}
else
{
string name = current.User.Identity.Name;
}
}
try
{
SqlConnectionHolder connection = null;
SqlDataReader reader = null;
try
{
connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
this.CheckSchemaVersion(connection.Connection);
SqlCommand command = new SqlCommand("dbo.aspnet_Profile_GetProperties", connection.Connection) {
CommandTimeout = this.CommandTimeout,
CommandType = CommandType.StoredProcedure
};
command.Parameters.Add(this.CreateInputParam("#ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
command.Parameters.Add(this.CreateInputParam("#UserName", SqlDbType.NVarChar, userName));
command.Parameters.Add(this.CreateInputParam("#CurrentTimeUtc", SqlDbType.DateTime, DateTime.UtcNow));
reader = command.ExecuteReader(CommandBehavior.SingleRow);
if (reader.Read())
{
names = reader.GetString(0).Split(new char[] { ':' });
values = reader.GetString(1);
int length = (int) reader.GetBytes(2, 0L, null, 0, 0);
buffer = new byte[length];
reader.GetBytes(2, 0L, buffer, 0, length);
}
}
finally
{
if (connection != null)
{
connection.Close();
connection = null;
}
if (reader != null)
{
reader.Close();
}
}
ProfileModule.ParseDataFromDB(names, values, buffer, svc);
if (HostingEnvironment.IsHosted && EtwTrace.IsTraceEnabled(4, 8))
{
EtwTrace.Trace(EtwTraceType.ETW_TYPE_PROFILE_END, HttpContext.Current.WorkerRequest, userName);
}
}
catch
{
throw;
}
}
internal static void ParseDataFromDB(string[] names, string values, byte[] buf, SettingsPropertyValueCollection properties)
{
if (((names != null) && (values != null)) && ((buf != null) && (properties != null)))
{
try
{
for (int i = 0; i < (names.Length / 4); i++)
{
string str = names[i * 4];
SettingsPropertyValue value2 = properties[str];
if (value2 != null)
{
int startIndex = int.Parse(names[(i * 4) + 2], CultureInfo.InvariantCulture);
int length = int.Parse(names[(i * 4) + 3], CultureInfo.InvariantCulture);
if ((length == -1) && !value2.Property.PropertyType.IsValueType)
{
value2.PropertyValue = null;
value2.IsDirty = false;
value2.Deserialized = true;
}
if (((names[(i * 4) + 1] == "S") && (startIndex >= 0)) && ((length > 0) && (values.Length >= (startIndex + length))))
{
value2.SerializedValue = values.Substring(startIndex, length);
}
if (((names[(i * 4) + 1] == "B") && (startIndex >= 0)) && ((length > 0) && (buf.Length >= (startIndex + length))))
{
byte[] dst = new byte[length];
Buffer.BlockCopy(buf, startIndex, dst, 0, length);
value2.SerializedValue = dst;
}
}
}
}
catch
{
}
}
}

http://www.karpach.com/Get-asp-net-profile-value-MS-SQL-database-using-T-SQL.htm
this helped me tremendously!
following the steps in that link allowed me to fetch any particular data in the PropertyValueString from the aspnet_profile table.
copying and pasting-
First Function:
CREATE FUNCTION dbo.fn_GetElement
(
#ord AS INT,
#str AS VARCHAR(8000),
#delim AS VARCHAR(1) )
RETURNS INT
AS
BEGIN
-- If input is invalid, return null.
IF #str IS NULL
OR LEN(#str) = 0
OR #ord IS NULL
OR #ord < 1
-- #ord > [is the] expression that calculates the number of elements.
OR #ord > LEN(#str) - LEN(REPLACE(#str, #delim, '')) + 1
RETURN NULL
DECLARE #pos AS INT, #curord AS INT
SELECT #pos = 1, #curord = 1
-- Find next element's start position and increment index.
WHILE #curord < #ord
SELECT
#pos = CHARINDEX(#delim, #str, #pos) + 1,
#curord = #curord + 1
RETURN
CAST(SUBSTRING(#str, #pos, CHARINDEX(#delim, #str + #delim, #pos) - #pos) AS INT)
END
Second Function:
CREATE FUNCTION dbo.fn_GetProfileElement
(
#fieldName AS NVARCHAR(100),
#fields AS NVARCHAR(4000),
#values AS NVARCHAR(4000))
RETURNS NVARCHAR(4000)
AS
BEGIN
-- If input is invalid, return null.
IF #fieldName IS NULL
OR LEN(#fieldName) = 0
OR #fields IS NULL
OR LEN(#fields) = 0
OR #values IS NULL
OR LEN(#values) = 0
RETURN NULL
-- locate FieldName in Fields
DECLARE #fieldNameToken AS NVARCHAR(20)
DECLARE #fieldNameStart AS INTEGER,
#valueStart AS INTEGER,
#valueLength AS INTEGER
-- Only handle string type fields (:S:)
SET #fieldNameStart = CHARINDEX(#fieldName + ':S',#Fields,0)
-- If field is not found, return null
IF #fieldNameStart = 0 RETURN NULL
SET #fieldNameStart = #fieldNameStart + LEN(#fieldName) + 3
-- Get the field token which I've defined as the start of the
-- field offset to the end of the length
SET #fieldNameToken = SUBSTRING(#Fields,#fieldNameStart,LEN(#Fields)-#fieldNameStart)
-- Get the values for the offset and length
SET #valueStart = dbo.fn_getelement(1,#fieldNameToken,':')
SET #valueLength = dbo.fn_getelement(2,#fieldNameToken,':')
-- Check for sane values, 0 length means the profile item was
-- stored, just no data
IF #valueLength = 0 RETURN ''
-- Return the string
RETURN SUBSTRING(#values, #valueStart+1, #valueLength)
END
SQL Query can be modded to your needs
SELECT dbo.fn_GetProfileElement('FirstName',PropertyNames,PropertyValuesString)
, dbo.fn_GetProfileElement('LastName',PropertyNames,PropertyValuesString)
FROM aspnet_Profile

For those who are still looking for a method to parse the aspnet_Profile table using pure SQL. Here is what I use:
First you need a Tally table. If you do not know what this is, read this article by Jeff Moden: http://www.sqlservercentral.com/articles/T-SQL/62867/
For you to generate the tally table use this script:
SELECT TOP 11000 IDENTITY(INT,1,1) AS N INTO dbo.Tally FROM Master.dbo.SysColumns sc1, Master.dbo.SysColumns sc2
--===== Add a Primary Key to maximize performance
ALTER TABLE dbo.Tally ADD CONSTRAINT PK_Tally_N PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100
--===== Let the public use it
GRANT SELECT, REFERENCES ON dbo.Tally TO PUBLIC
Now on to parsing the ProfileData:
The process below is the fastest way I found to do this after lots of testing on my specific data. I have tested parsing the complete table in one go, but that runs slower than using the function below and parsing one user at a time with a CROSS APPLY.
So to call the function, use something like:
SELECT bla, bla
FROM aspnet_Users u CROSS APPY dbo.ProfileProperties(u.UserID)
The only thing you need to do is to update 3 things to contain the Profile Properties that you use:
1) the return table
2) the PIVOT statement, and
3) the insert statement copying the data from the PIVOT into the return table
Here is the function, Enjoy!
/** =============================================
** Author: Francois Grobler
** Create date: 2013-04-25
** Description: This function extracts all
** Profile Properties for a given UserId,
** and returns them as a table
** Change History:
** Date: Author: Change:
**
** ============================================= **/
CREATE FUNCTION dbo.ProfileProperties
(
#UserID UNIQUEIDENTIFIER
)
RETURNS #returnTable TABLE(
FirstName nvarchar(200)
, LastName nvarchar(200)
, PassportNumber nvarchar(100)
, PositionCode int
, CellNumber nvarchar(20)
, Telephone nvarchar(30)
, FaxNumber nvarchar(20)
, Email nvarchar(200)
, PersalNumber nvarchar(10)
, SouthAfricanIdentityNumber nchar(13)
, ContractNumber nvarchar(20)
, DepartmentName nvarchar(200)
, SiteName nvarchar(200)
, DepartmentCode int
, SiteCode int
, UserAccessCode int
, ApproverCode int
)
WITH SCHEMABINDING
AS
BEGIN
WITH Properties(PropertyNo, PropertyType, UserId, Value)
AS
(
SELECT (ROW_NUMBER() OVER(ORDER BY UserId) - 1) / 4 PropertyNo
, (ROW_NUMBER() OVER(PARTITION BY p.UserId ORDER BY UserId) - 1) % 4 PropertyType
, p.UserId
, SUBSTRING(':' + CONVERT(nvarchar(4000), p.PropertyNames), n + 1, CHARINDEX(':', ':' + CONVERT(nvarchar(4000), p.PropertyNames), n + 1) - n - 1) Value
FROM dbo.Tally, dbo.aspnet_Profile p
WHERE n < LEN(':' + CONVERT(nvarchar(4000), p.PropertyNames))
and SUBSTRING(':' + CONVERT(nvarchar(4000), p.PropertyNames), n, 1) = ':'
and p.UserId = #UserID
)
, FlatProperties(UserId, Property, ValueType, StartIndex, ValueLength)
AS
(
SELECT UserId
, MAX(CASE WHEN PropertyType = 0 THEN Value ELSE '' END) Property
, MAX(CASE WHEN PropertyType = 1 THEN Value ELSE '' END) ValueType
, MAX(CASE WHEN PropertyType = 2 THEN CONVERT(int, Value) + 1 ELSE 0 END) StartIndex
, MAX(CASE WHEN PropertyType = 3 THEN CONVERT(int, Value) ELSE 0 END) ValueLength
FROM
Properties
GROUP BY UserID, PropertyNo
)
, PropertyValues(UserID, PropertyName, PropertyValue)
AS
(
SELECT p.UserID, fp.Property
, CASE fp.ValueType
WHEN 'S' THEN SUBSTRING(p.PropertyValuesString, fp.StartIndex, fp.ValueLength)
ELSE SUBSTRING(p.PropertyValuesBinary, fp.StartIndex, fp.ValueLength) END Value
FROM dbo.aspnet_Profile p INNER JOIN flatProperties fp ON p.UserId = fp.UserId
WHERE p.UserId = #UserID
)
, PropertyTable
AS
(
SELECT
UserID
, pvt.[FirstName]
, pvt.[LastName]
, pvt.[PassportNumber]
, pvt.[PositionCode]
, pvt.[CellNumber]
, pvt.[Telephone]
, pvt.[FaxNumber]
, pvt.[Email]
, pvt.[PersalNumber]
, pvt.[SouthAfricanIdentityNumber]
, pvt.[ContractNumber]
, pvt.[DepartmentName]
, pvt.[SiteName]
, pvt.[DepartmentCode]
, pvt.[SiteCode]
, pvt.[UserCode] UserAccessCode
, pvt.[ApproverCode]
FROM PropertyValues
PIVOT (
MAX(PropertyValue) FOR PropertyName IN ([FirstName],[LastName],[PassportNumber],[PositionCode],[CellNumber],[Telephone],[FaxNumber],[Email],[PersalNumber],[SouthAfricanIdentityNumber],[ContractNumber],[DepartmentName],[SiteName],[DepartmentCode],[SiteCode],[UserCode],[ApproverCode])
) AS pvt
)
INSERT INTO #returnTable
(
FirstName
, LastName
, PassportNumber
, PositionCode
, CellNumber
, Telephone
, FaxNumber
, Email
, PersalNumber
, SouthAfricanIdentityNumber
, ContractNumber
, DepartmentName
, SiteName
, DepartmentCode
, SiteCode
, UserAccessCode
, ApproverCode
)
SELECT TOP 1
FirstName
, LastName
, PassportNumber
, PositionCode
, CellNumber
, Telephone
, FaxNumber
, Email
, PersalNumber
, SouthAfricanIdentityNumber
, ContractNumber
, DepartmentName
, SiteName
, DepartmentCode
, SiteCode
, UserAccessCode
, ApproverCode
FROM PropertyTable;
RETURN;
END
GO

Related

BigQuery JavaScript UDF to call Array with values from SQL query

I am trying to write my First Bigquery UDF function (converting Oracle Function) and thanks to SO for the help so far I am able to write partial code as shown below,
My task is when we pass the parameters like admit_date, input1, input2 are passed and discharge date should be calculated based on few calculations (not weekends or Holidays).
Apologies for any mistakes or any trouble
Here is my code :
DECLARE list ARRAY <STRING>;
DECLARE v_holiday STRING DEFAULT 'No';
DECLARE v_due_report INT64;
DECLARE v_due_report_cnt INT64;
DECLARE v_days INT64;
DECLARE p_date DATE;
DECLARE p_input1 STRING;
DECLARE p_input2 STRING;
DECLARE v_bus_day STRING;
DECLARE v_cnt INT64 DEFAULT 1;
DECLARE v_max_days INT64 DEFAULT 1;
#SET v_holiday = (SELECT CASE WHEN EXISTS (SELECT 1 FROM `examples.date_calendar` WHERE HOLIDAY = DATE(p_date)) THEN 'Yes' ELSE 'No' END);
select ARRAY(SELECT holiday from `examples.date_calendar`) AS list;
SET v_due_report_cnt = (SELECT COUNT(*) FROM `examples.report_assessments` WHERE p_date BETWEEN START_DATE AND END_DATE
AND p_input1 = ICD_9_CLASS AND p_input2 = LAST_MEDICATION);
CREATE TEMP FUNCTION patient_report_date(p_admit_date DATE, p_input1 STRING,p_input2 STRING)
RETURNS STRING
LANGUAGE js AS """
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var dayName = days[p_admit_date.getDay()];
if(p_admit_date < Date.parse("2016-02-01") {
v_bus_day = p_admit_date.setDate(date.getDate() + 2);
return v_bus_day;
}
# SET v_HOLIDAY = (SELECT CASE WHEN EXISTS (SELECT 1 FROM `examples.date_calendar` WHERE HOLIDAY = TRUNC(p_admit_date)) THEN 'Yes' ELSE 'No' END)
if(!(dayName) in ('Saturday', 'Sunday')) && (v_holiday == 'No'){
v_days = 2;
}
else {
v_days = 3;
p_date_trunc_time = new Date(p_date.getFullYear(), p_date.getMonth(), p_date.getDate());
v_bus_day = new Date(p_date_trunc_time.setSeconds(p_date_trunc_time.getSeconds() + 1));
}
if(p_admit_date < Date.parse("2020-07-01") {
v_due_report = 0
}
#SET v_due_report_cnt = (SELECT COUNT(*) FROM `examples.report_assessments` WHERE p_admit_date BETWEEN START_DATE AND END_DATE
#AND p_input1 = ICD_9_CLASS AND p_input2 = LAST_MEDICATION);
else if (v_due_report_cnt > 0) {
v_due_report = 4
}
v_days = v_days + v_due_report;
while max_days <= v_days {
if (! days[(p_admit_date + day).getDay()] in ('Saturday','Sunday') && (list.indexOf(p_admit_date)==-1) {
v_cnt++
max_days++
}
day++
}
v_bus_day = p_admit_date + v_vcnt;
return v_bus_day
""";
WITH data_date AS (
SELECT DATE("2021-05-31") AS p_DATE, "ICD8081" AS p_input1, "CDE2" AS p_input2 UNION ALL
SELECT DATE("2021-05-30"),"ICD8211","DER2"
)
SELECT p_DATE,
p_input1,
p_input2,
patient_report_date(p_DATE,p_input1,p_input2) discharge_date
FROM data_date;
When I executed the function it throwed me error "SyntaxError: Unexpected Token"
any suggestions or feedback on this code would be helpful.
Appreciate your help
Thanks for reading my post.
Updated Code: Finally, I am able to get my code working, want to add in SO so it might be useful to someone.
DECLARE holiday_list ARRAY <STRING>;
DECLARE holiday_weekend ARRAY <STRING>;
DECLARE report_assessments ARRAY <STRUCT<ICD_9_CLASS STRING,LAST_MEDICATION STRING>>;
DECLARE p_admit_date DATE;
DECLARE p_input1 STRING;
DECLARE p_input2 STRING;
SET holiday_list = (SELECT ARRAY(SELECT CAST(holiday AS STRING) FROM `examples.date_calendar`));
SET v_due_report = (SELECT ARRAY(SELECT STRUCT(CAST(ICD_9_CLASS AS STRING) AS ICD_9_CLASS, CAST(LAST_MEDICATION AS STRING) AS LAST_MEDICATION) FROM `examples.report_assessments`));
CREATE TEMP FUNCTION patient_report_date(p_admit_date DATE, p_input1 STRING,p_input2 STRING)
RETURNS STRING
LANGUAGE js AS """
var days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var holiday_weekend = ['Saturday','Sunday'];
var v_signature=0;
var v_days=0;
var v_day =1;
var v_cnt=0;
var v_max_days=1;
if(p_admit_date < new Date("2016-02-01")) {
p_admit_date.setDate(p_admit_date.getDate() + 2);
}
else
{
if((holiday_weekend.indexOf(days[p_admit_date.getDay()]) === -1) && (holiday_list.indexOf(p_admit_date) === -1)) {
v_days = 2;
}
else {
   v_days = 3;
}
for(var i = 0; i < report_assessments.length; i++) {
if ((report_assessments[i]['ICD_9_CLASS'] === p_input1) && (signature_assessments[i]['LAST_MEDICATION'] === p_input2)) {
v_signature++;
}
}
if (p_admit_date < Date("2020-07-01") && (v_signature === 0)) {
v_days = v_days;
}
else if (v_signature > 0) {
v_days = v_days + 4;
}
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
while max_days <= v_days {
if ((holiday_list.indexOf(addDays(p_admit_date,v_day).toISOString().slice(0, 10)) === -1) && (holiday_weekend.indexOf(days[addDays(p_admit_date,v_day).getUTCDay()]) === -1)) {
v_max_days++;
}
v_day++;
v_cnt++;
}
p_admit_date.setDate(p_admit_date.getDate() + v_cnt);
}
return p_admit_date;
""";
WITH data_date AS (
SELECT DATE("2021-05-31") AS p_DATE, "ICD8081" AS p_input1, "CDE2" AS p_input2,holiday_list, report_assessments UNION ALL
SELECT DATE("2021-05-30"),"ICD8211","DER2",holiday_list, report_assessments
)
SELECT p_DATE,
p_input1,
p_input2,
patient_report_date(p_DATE,p_input1,p_input2,holiday_list, report_assessments) discharge_date
FROM `examples.tabledata`; ```
Yes, javascript UDFs are also persistent. Just remove TEMP and optinally specify project name and dataset name:
CREATE FUNCTION project_name.dataset_name.patient_report_date(...)

SQL : recursive looping

Table is as follows:
I'm trying to get the result set to have groups of all person that intersects from the table, hence creating following groups in result set from attached table.
Person1, Person2, Person3, Person7, Person8
Person5, Person6, Person9
So far I have following query, but can't seem to get the results intersected on a table of rows and outputted as 1 column.
DECLARE #r VARCHAR(MAX), #n INT, #i INT
SELECT #i = 1,
#r = 'SELECT BOX, ' + CHAR(13),
#n = (SELECT TOP 1 COUNT( USERS )
FROM EXCHANGE
GROUP BY BOX
ORDER BY COUNT( USERS ) DESC ) ;
WHILE #i <= #n BEGIN
SET #r = #r +
CASE WHEN #i = 1
THEN 'MAX( CASE Seq WHEN ' + CAST( #i AS VARCHAR ) + '
THEN USERS
ELSE SPACE(0) END ) + ' + CHAR(13)
WHEN #i = #n
THEN 'MAX( CASE Seq WHEN ' + CAST( #i AS VARCHAR ) + '
THEN '', '' + USERS
ELSE SPACE(0) END ) ' + CHAR(13)
ELSE 'MAX( CASE Seq WHEN ' + CAST( #i AS VARCHAR ) + '
THEN '', '' + USERS
ELSE SPACE(0) END ) + ' + CHAR(13)
END ;
SET #i = #i + 1 ;
END
SET #r = #r + '
FROM ( SELECT BOX, USERS,
ROW_NUMBER() OVER ( PARTITION BY BOX ORDER BY USERS )
FROM EXCHANGE p ) D ( BOX, USERS, Seq )
GROUP BY BOX;'
EXEC( #r ) ;
This type of graph walking is a pain in SQL Server -- you have cycles. The problem is avoiding cycles. Because SQL Server doesn't have very good data types, you need to store the visited nodes as strings.
You can do all this in a recursive CTE. The idea is to follow all paths from a node without repeating any node. Keep the minimum node visited. Voila! That specifies the path:
with cte as (
select box, users,
convert(varchar(max), concat(',', box, ',', users, ',')) as path,
(case when box < users then box else users end) as min_node
from exchange
union all
select cte.box, e.users,
concat(cte.path, e.users, ','),
(case when min_node < e.users then min_node else e.users end)
from cte join
exchange e
on e.box = cte.users
where path not like '%,' + e.users + ',%'
)
select cte.box, min(cte.users), min(cte.path), min(cte.min_node) as grouping
from cte
group by cte.box;
Here is a db<>fiddle.
This assumes that the edges are symmetric, so if you have (a, b), you also have (b, a).
If this is not the case, it is easy to add a CTE that makes this the case:
select box, users
from exchange
union -- on purpose to remove duplicates
select users, box
from exchange;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RecusriveGroup
{
public class FinalResult
{
public string GroupName { get; set; }
public string BoxName { get; set; }
public string UserName { get; set; }
}
class Program
{
static void Main(string[] args)
{
using(var con = new SqlConnection("Data Source=SQLServer;Initial Catalog=TESTDB;Integrated Security=SSPI"))
{
con.Open();
var cmd = new SqlCommand("select distinct Box from Exchange");
cmd.Connection = con;
var adapter = new SqlDataAdapter(cmd);
DataSet dsResult = new DataSet();
adapter.Fill(dsResult);
var finalResult = new List<FinalResult>();
var groupId = 0;
foreach (DataRow row in dsResult.Tables[0].Rows)
{
if(finalResult.Any(f => f.BoxName.Equals(row["Box"])))
{
continue;
}
groupId++;
RecursiveCall("Group" + groupId, row["Box"].ToString(), "", con, finalResult);
}
foreach(var result in finalResult)
{
var cmd1 = new SqlCommand("INSERT INTO FinalResult(Box, [User], [Group]) VALUES(#Box, #User, #Group)", con);
cmd1.Parameters.AddWithValue("#Box", result.BoxName);
cmd1.Parameters.AddWithValue("#User", result.UserName);
cmd1.Parameters.AddWithValue("#Group", result.GroupName);
cmd1.ExecuteNonQuery();
}
}
Console.ReadLine();
}
private static void RecursiveCall(string groupName, string boxName, string userName, SqlConnection sqlConnection, List<FinalResult> finalResult)
{
DataSet dsResult = new DataSet();
if (!string.IsNullOrEmpty(boxName) && !string.IsNullOrEmpty(userName))
{
var cmd = new SqlCommand("select Box, Users from Exchange WHERE Box = #BoxName OR Users = #UserName");
cmd.Parameters.AddWithValue("#BoxName", boxName);
cmd.Parameters.AddWithValue("#UserName", userName);
cmd.Connection = sqlConnection;
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(dsResult);
}
else if(!string.IsNullOrEmpty(boxName))
{
var cmd = new SqlCommand("select Box, Users from Exchange WHERE Box = #BoxName");
cmd.Parameters.AddWithValue("#BoxName", boxName);
cmd.Connection = sqlConnection;
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(dsResult);
}
else
{
var cmd = new SqlCommand("select Box, Users from Exchange WHERE Users = #UserName");
cmd.Parameters.AddWithValue("#UserName", userName);
cmd.Connection = sqlConnection;
var adapter = new SqlDataAdapter(cmd);
adapter.Fill(dsResult);
}
foreach (DataRow row in dsResult.Tables[0].Rows)
{
if (finalResult.Any(f => f.BoxName.Equals(row["Box"].ToString()) && f.UserName.Equals(row["Users"].ToString())))
{
continue;
}
finalResult.Add(new FinalResult() { GroupName = groupName, BoxName = row["Box"].ToString(), UserName = row["Users"].ToString() });
RecursiveCall(groupName, row["Box"].ToString(), row["Users"].ToString(), sqlConnection, finalResult);
}
}
}
}

Changing datetime to date data type?

ALTER PROCEDURE [Deal].[USP_LoadDealHistoryByDealId]
(#DealId int,
#chk int)
AS
IF (#chk = 1)
BEGIN
SELECT
DDT.FieldType AS field,
DDT.OldValue as old,
DDT.NewValue as new,
AU.FullName AS Name,
DDT.UpdateOn AS UpdatedOn
FROM
[Deal].[DealTransaction] as DDT
INNER JOIN
AD.Users as AU ON AU.UserId = DDT.[UpdateBy]
WHERE
DDT.dealId = #DealId
END
ELSE if(#chk = 2)
BEGIN
SELECT
'No Data' as field ,
0 as old ,
0 as new ,
AU.FullName AS Name,
DD.UpdatedOn AS UpdatedOn
FROM
AD.Users as AU
INNER JOIN
[Deal].[Deals] AS DD ON AU.UserId = DD.UploadedBy
WHERE
DD.dealId = #DealId
END
UpdatedOn column is of datatype datetime and it shows to my HTML table like 10-09-1992/12.00.... But I want to show just date like 10-09-1992, what should I do?
Here Is my HTML table
public string LoadDealHistory(DealHistory aDealhistory)
{
StringBuilder html = new StringBuilder();
try {
using (DealTranctionGateway dealTranctionGateway = new DealTranctionGateway())
{
DataTable dt = new DataTable();
dt = dealTranctionGateway.LoadDealHistory(aDealhistory);
string dealHistory = "";
if (dt.Rows.Count > 0)
{
html.Append("<table class='table table-bordered'>");
html.Append("<thead>");
html.Append("<tr>");
html.Append("<th>S.No</th>");
html.Append("<th>FieldType</th>");
html.Append("<th>OldValue</th>");
html.Append("<th>NewValue</th>");
html.Append("<th>Full Name</th>");
html.Append("<th>UpdateOn</th>");
html.Append("</thead>");
html.Append("</tr>");
for (int i = 0; i < dt.Rows.Count; i = i + 1)
{
int sNo = i + 1;
html.Append("<tr>");
html.Append("<td>" + sNo + "</td>");
html.Append("<td>" + dt.Rows[i]["field"] + "</td>");
html.Append("<td>" + dt.Rows[i]["old"] + "</td>");
html.Append("<td>" + dt.Rows[i]["new"] + "</td>");
html.Append("<td>" + dt.Rows[i]["Name"] + "</td>");
html.Append("<td>" + dt.Rows[i]["UpdatedOn"] + "</td>");
html.Append("</tr>");
}
html.Append("</tbody>");
html.Append("</table>");
}
}
}
catch (Exception ex)
{
}
return html.ToString();
}
}
Updated:
Tried this:
string updateOn = "";
updateOn = ((DateTime)dt.Rows[i]["UpdatedOn"]).ToString("dd-MM-yyyy", CultureInfo.InvariantCulture);
html.Append("<td>" + updateOn + "</td>");
OR
You can use format DateTime in SQL:
More format at here.
In your case, it should be using style 105.
SELECT replace(convert(NVARCHAR, UpdatedOn, 105), ' ', '-')
You can convert it to string like:
dt.Rows[i]["UpdatedOn"].ToString("dd-MM-yyyy")
No need for any changes on SQL Server side, date formatting is a front-end problem.
Select convert(date,getdate())

Executing parameterized stored procedures using PetaPoco

It's been two days I'm wrestling with PetaPoco to implement a search solution (evidently with some search parameters) which has custom paging in database. I couldn't figure out how to configure PetaPoco paging with ASP.NET DataPager (which is a whole different question). Anyway I want to use custom paging in database.
I have a stored proc called GetUsersPaged like below:
ALTER PROCEDURE [dbo].[GetUsersPaged]
#startRowIndex int,
#maximumRows int,
#name nvarchar(300) = NULL,
#email nvarchar(100) = NULL
AS
BEGIN
SELECT *
FROM
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY Id) AS RowRank
FROM UserInfo
WHERE
(Nickname LIKE '%'+#name+'%'
OR FirstName LIKE '%'+#name+'%'
OR LastName LIKE '%'+#name+'%'
OR #name IS NULL)
AND
(Email = #email OR #email IS NULL)
) AS UsersPagedList
WHERE RowRank BETWEEN #startRowIndex AND (#startRowIndex + #maximumRows)
END
and GetUsersCount stored proc like below:
ALTER PROCEDURE [dbo].[GetUsersCount]
#name nvarchar(300) = NULL,
#email nvarchar(100) = NULL
AS
BEGIN
SELECT COUNT(*)
FROM UserInfo
WHERE
(Nickname LIKE '%'+#name+'%'
OR FirstName LIKE '%'+#name+'%'
OR LastName LIKE '%'+#name+'%'
OR #name IS NULL)
AND
(Email = #email OR #email IS NULL)
END
Now I have two methods for calling these stored procs like below:
[DataObjectMethod(DataObjectMethodType.Select, false)]
public List<DAL.UserInfo> GetPagedUserSearchResults(int startRowIndex, int pageSize, string name, string email)
{
DBService dbService = new DBService();
var db = dbService.GetDatabase();
var list = new List<DAL.UserInfo>();
if(name != string.Empty && email != string.Empty)
list = db.Fetch<DAL.UserInfo>(#"EXEC GetUsersPaged ##startRowIndex = #0, ##maximumRows = #1,
##name = #2, ##email = #3", startRowIndex, pageSize, name, email);
else if(name == string.Empty && email != string.Empty)
list = db.Fetch<DAL.UserInfo>(#"EXEC GetUsersPaged ##startRowIndex = #0, ##maximumRows = #1,
##email = #2", startRowIndex, pageSize, email);
else if(name != string.Empty && email == string.Empty)
list = db.Fetch<DAL.UserInfo>(#"EXEC GetUsersPaged ##startRowIndex = #0, ##maximumRows = #1,
##name = #2", startRowIndex, pageSize, name);
else if(name == string.Empty && email == string.Empty)
list = db.Fetch<DAL.UserInfo>(#"EXEC GetUsersPaged ##startRowIndex = #0, ##maximumRows = #1"
,startRowIndex, pageSize);
return list;
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public int GetPagedUserSearchResultsCount(string name, string email)
{
DBService dbService = new DBService();
var db = dbService.GetDatabase();
IEnumerable<DAL.UserInfo> count = null;
if (name != string.Empty && email != string.Empty)
count = db.Query<DAL.UserInfo>("EXEC GetUsersCount ##name = #0, ##email = #1", name, email);
else if (name == string.Empty && email != string.Empty)
count = db.Query<DAL.UserInfo>("EXEC GetUsersCount ##email = #0", email);
else if(name != string.Empty && email == string.Empty)
count = db.Query<DAL.UserInfo>("EXEC GetUsersCount ##name = #0", name);
else if (name == string.Empty && email == string.Empty)
count = db.Query<DAL.UserInfo>("EXEC GetUsersCount");
return count.Count<DAL.UserInfo>();
}
My question is: everything is fine when I'm executing and testing stored procs in db (inside SQL Management Studio). All results respect to paging parameters. But when I call the same stored procs using PetaPoco, it fetches the whole thing and paging is ignored.
For example when I test stored procs in SQL Management Studio with
#startRowIndex = 0
#maximumRows = 1
and I don't send anything for #name and #email, it returns just one row which is totally correct. But the same things with PetaPoco, it returns 3 rows in the list. Any idea what's the problem?
Have you tried setting EnableAutoSelect = false? When I left this on the default setting, the call returned all records.

See SQL From EntityFramework with Collection-like Queries

I do not have 'full' the version of MS SQL (SQL Express 2008) so I do not have the profiler tool.
I want to see the SQL generated by my Entity Framework code, but all of the examples I find use the
var x = from u in table
select u;
type of syntax; But most of my queries are more like ..
var x = context.Users.Single(n => n.Name == "Steven");
type of syntax. What can I do to see the SQL generated, from this manner of coding? Any ideas?
check out this link... it has a tracing provider for EF4.
I'll try to give an example based on how I'm using this in a unit test.
Step 1: Register the provider
There are a couple ways to configure the provider. For my unit tests I configured the provider in code by calling the static method RegisterProvider();
[AssemblyInitialize()]
public static void AssemblyInit(TestContext context) {
EFTracingProviderConfiguration.RegisterProvider();
}
Step 2: Create a sub-class of your entity model to provide the tracing extensions
public partial class ExtendedNorthwindEntities : NorthwindEntities {
private TextWriter logOutput;
public ExtendedNorthwindEntities(string connectionString)
: base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
connectionString,
"EFTracingProvider")) {
}
#region Tracing Extensions
private EFTracingConnection TracingConnection {
get { return this.UnwrapConnection<EFTracingConnection>(); }
}
public event EventHandler<CommandExecutionEventArgs> CommandExecuting {
add { this.TracingConnection.CommandExecuting += value; }
remove { this.TracingConnection.CommandExecuting -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFinished {
add { this.TracingConnection.CommandFinished += value; }
remove { this.TracingConnection.CommandFinished -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFailed {
add { this.TracingConnection.CommandFailed += value; }
remove { this.TracingConnection.CommandFailed -= value; }
}
private void AppendToLog(object sender, CommandExecutionEventArgs e) {
if (this.logOutput != null) {
this.logOutput.WriteLine(e.ToTraceString().TrimEnd());
this.logOutput.WriteLine();
}
}
public TextWriter Log {
get { return this.logOutput; }
set {
if ((this.logOutput != null) != (value != null)) {
if (value == null) {
CommandExecuting -= AppendToLog;
}
else {
CommandExecuting += AppendToLog;
}
}
this.logOutput = value;
}
}
#endregion
}
Step 3: Attach to the Log property
var context = new ExtendedNorthwindEntities("name=\"NorthwindEntities\"");
context.Log = System.Console.Out;
Does Express Edition support extended events? If so this will capture statement and sp completed events in a similar way to Profiler.
Edit: I have changed it to use a memory target rather than a file target. Ideally uncomment the WHERE sections and replace with an appropriate user name to capture only events of interest or you can filter by spid with WHERE (([sqlserver].[session_id]=(56))) for example.
IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='test_trace')
DROP EVENT SESSION [test_trace] ON SERVER;
CREATE EVENT SESSION [test_trace]
ON SERVER
ADD EVENT sqlserver.sp_statement_completed(
ACTION (package0.callstack, sqlserver.session_id, sqlserver.sql_text)
-- WHERE (([sqlserver].[username]='Domain\Username'))
),
ADD EVENT sqlserver.sql_statement_completed(
ACTION (package0.callstack, sqlserver.session_id, sqlserver.sql_text)
--WHERE (([sqlserver].[username]='Domain\Username'))
)
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY = 4096KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 1 SECONDS, MAX_EVENT_SIZE = 0KB,
MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF, STARTUP_STATE = OFF)
ALTER EVENT SESSION [test_trace] ON SERVER STATE = START
And to review the results (Query generated using Adam Machanic's XE Code Generator)
DECLARE
#session_name VARCHAR(200) = 'test_trace'
SELECT
pivoted_data.*
FROM
(
SELECT MIN(event_name) AS event_name,
MIN(event_timestamp) AS event_timestamp,
unique_event_id,
CONVERT ( BIGINT, MIN (
CASE
WHEN d_name = 'cpu'
AND d_package IS NULL
THEN d_value
END ) ) AS [cpu],
CONVERT ( BIGINT, MIN (
CASE
WHEN d_name = 'duration'
AND d_package IS NULL
THEN d_value
END ) ) AS [duration],
CONVERT ( BIGINT, MIN (
CASE
WHEN d_name = 'object_id'
AND d_package IS NULL
THEN d_value
END ) ) AS [object_id],
CONVERT ( INT, MIN (
CASE
WHEN d_name = 'object_type'
AND d_package IS NULL
THEN d_value
END ) ) AS [object_type],
CONVERT ( DECIMAL(28,0), MIN (
CASE
WHEN d_name = 'reads'
AND d_package IS NULL
THEN d_value
END ) ) AS [reads],
CONVERT ( VARCHAR(MAX), MIN (
CASE
WHEN d_name = 'session_id'
AND d_package IS NOT NULL
THEN d_value
END ) ) AS [session_id],
CONVERT ( INT, MIN (
CASE
WHEN d_name = 'source_database_id'
AND d_package IS NULL
THEN d_value
END ) ) AS [source_database_id],
CAST((SELECT CONVERT ( VARCHAR(MAX), MIN (
CASE
WHEN d_name = 'sql_text'
AND d_package IS NOT NULL
THEN d_value
END ) ) AS [processing-instruction(x)] FOR XML PATH('') ) AS XML) AS [sql_text],
CONVERT ( DECIMAL(28,0), MIN (
CASE
WHEN d_name = 'writes'
AND d_package IS NULL
THEN d_value
END ) ) AS [writes]
FROM
(
SELECT
*,
CONVERT(VARCHAR(400), NULL) AS attach_activity_id
FROM
(
SELECT
event.value('(#name)[1]', 'VARCHAR(400)') as event_name,
event.value('(#timestamp)[1]', 'DATETIME') as event_timestamp,
DENSE_RANK() OVER (ORDER BY event) AS unique_event_id,
n.value('(#name)[1]', 'VARCHAR(400)') AS d_name,
n.value('(#package)[1]', 'VARCHAR(400)') AS d_package,
n.value('((value)[1]/text())[1]', 'VARCHAR(MAX)') AS d_value,
n.value('((text)[1]/text())[1]', 'VARCHAR(MAX)') AS d_text
FROM
(
SELECT
(
SELECT
CONVERT(xml, target_data)
FROM sys.dm_xe_session_targets st
JOIN sys.dm_xe_sessions s ON
s.address = st.event_session_address
WHERE
s.name = #session_name
AND st.target_name = 'ring_buffer'
) AS [x]
FOR XML PATH(''), TYPE
) AS the_xml(x)
CROSS APPLY x.nodes('//event') e (event)
CROSS APPLY event.nodes('*') AS q (n)
) AS data_data
) AS activity_data
GROUP BY
unique_event_id
) AS pivoted_data;