Thursday, October 27, 2011

ALTER TABLE Impact to Foreign Keys, Primary Key, Default Constraints, Unique Constraints, and Indexes

So you set up a look up table using a type [integer] for the primary key?   

But there are only 15 rows and the table will never have more than 255 rows.  So why not use a [tinyint] type for the primary key instead? 

Well, if you thought of this ahead of time, great.  

If you didn't and default constraints and foreign key relationships are already set up, you have to drop those and re-create them.
Otherwise, you'll get errors:

The object 'PK_VTypeID' is dependent on column 'VTypeID'
The object 'FK_Man_VType_VType' is dependent on column 'VTypeID'.
ALTER TABLE ALTER COLUMN VTypeID failed because one or more objects access this column.
Column already has a DEFAULT bound to it.
Could not create constraint. See previous errors.
The operation failed because an index or statistics with name 'IDXUQ_Manufacturer_VehichleTypes'  ..'.

To drop a foreign key constraint

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Vehicle_Type]') AND parent_object_id = OBJECT_ID(N'[dbo].[Vehicles]'))
ALTER TABLE [dbo].[Vehicles] DROP CONSTRAINT [FK_Vehicle_Type]
GO

To drop a default constraint

IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF_Vehicle_VType]') AND type = 'D')
ALTER TABLE [dbo].Vehicles] DROP CONSTRAINT [DF__Veh__VType__7AC02C80]
GO

-- find the Table Name, Column Name, and Default Value given a Default Contstraint Name  --just in case the name doesn't clue you into table name and column name.

SELECT so1.name as [Default Name]
, so2.name as [Table]
, scl.name as [Column]
,df.definition as [Definition]
,df.is_system_named
FROM dbo.sysobjects so1 
INNER JOIN sysconstraints scn ON so1.id = scn.constid 
INNER JOIN sysobjects so2 ON so1.parent_obj = so2.id
INNER JOIN syscolumns scl ON scl.colid = scn.colid AND scl.id = so1.parent_obj
INNER JOIN sys.default_constraints df ON parent_column_id = scl.colid AND so1.id = df.object_id
WHERE so1.name = 'DF__Loc8__DST__430CD787'

To get a list of constraints in a table use the system stored procedure sp_helpConstraint. It's [constraint_keys] column is derived from the [definition] column from the sys.default_constraints table.

exec sp_helpConstraint Loc8

Querying the INFORMATION_SCHEMA does not return the default constraint name, and the first two commands don't even include default constrains in the result. INFORMATION_SCHEMA.COLUMNS does show the default definition/constraint_keys

select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_NAME = 'DF__Loc8__DST__430CD787' OR TABLE_NAME='Loc8'

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_NAME = 'DF__Loc8__DST__430CD787' OR TABLE_NAME='Loc8'

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Loc8'


Wednesday, October 26, 2011

Course, Class, Students, Exams, Quizes, and Tests SQL Server Schema Example

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
DECLARE @Show bit = 1

CREATE TABLE [tbl_Courses](

    [CourseID] [int] IDENTITY(11,1) NOT NULL 
        CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED ([CourseID]),
       
    [Course] [nvarchar](50) NOT NULL
        CONSTRAINT [UQ_Course] UNIQUE NONCLUSTERED ([Course])
)

CREATE TABLE tbl_Users (
    UserID int not null identity(222,1) CONSTRAINT PK_User PRIMARY KEY (UserID),
    [Name] nvarchar(20),
    Student bit CONSTRAINT DF_Student DEFAULT (1),
    Teacher bit CONSTRAINT DF_Teacher DEFAULT (0)
)

CREATE TABLE tbl_CourseStudents (
    CourseStudentID int not null identity(333,1)
        CONSTRAINT PK_CourseStudent PRIMARY KEY (CourseStudentID),
       
    UserID int CONSTRAINT FK_CourseStudents_U FOREIGN KEY ([UserID])
        REFERENCES tbl_Users([UserID]),
   
    [CourseID] [int] CONSTRAINT FK_CourseStudents_C FOREIGN KEY ([CourseID])
        REFERENCES tbl_Courses([CourseID])       
)

CREATE TABLE [dbo].[tbl_Quizes](

    [QuizID] [int] IDENTITY(4444,1) NOT NULL 
        CONSTRAINT [PK_Quiz] PRIMARY KEY CLUSTERED ([QuizID]),
       
    [Quiz] [nvarchar](50) NOT NULL
        CONSTRAINT [UQ_Quiz] UNIQUE NONCLUSTERED ([Quiz]),
       
    [CourseID] [int] NOT NULL
        CONSTRAINT FK_Quiz_Course FOREIGN KEY ([CourseID])
        REFERENCES tbl_Courses([CourseID])       
)

CREATE TABLE [dbo].[tbl_Questions](

    [QuestionID] [int] IDENTITY(55555,1) NOT NULL 
        CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([QuestionID]),
       
    [Question] [nvarchar](50) NOT NULL
        CONSTRAINT [UQ_Question] UNIQUE NONCLUSTERED ([Question]),

    [QuizID] [int] NOT NULL
        CONSTRAINT FK_Question_Quiz FOREIGN KEY ([QuizID])
        REFERENCES tbl_Quizes([QuizID]),
       
    [Points] tinyint  --how much is answering this question worth?
)

CREATE TABLE [dbo].[tbl_Choices](

    [QuestionID] [int] NOT NULL
        CONSTRAINT FK_Choice_Question FOREIGN KEY ([QuestionID])
        REFERENCES tbl_Questions([QuestionID]),

    [ChoiceID] [int] IDENTITY(666666,1) NOT NULL 
        CONSTRAINT [PK_Choice] PRIMARY KEY CLUSTERED ([ChoiceID]),
       
    [Choice] [nvarchar](50) NOT NULL
        CONSTRAINT [UQ_Choice] UNIQUE NONCLUSTERED ([QuestionID], [Choice]),
       
    [Correct] bit NULL

    )

CREATE TABLE tbl_Responses(

    [UserID] int
        CONSTRAINT FK_Response_User_U FOREIGN KEY (UserID)
        REFERENCES tbl_Users(UserID),

    [QuestionID] int not null
        CONSTRAINT FK_User_Question_A FOREIGN KEY ([QuestionID])
        REFERENCES [dbo].[tbl_Questions]([QuestionID]),

    [ChoiceID] int null,
   
    [Response] nvarchar(max) null,  -- text response
   
    [Points] smallint -- tinyint only goes up to 255
)

GO
CREATE PROCEDURE StudentsInCourse @CourseID int
AS
    SELECT c.CourseID, Course, u.UserID, [Name] AS [Student]
        FROM tbl_CourseStudents cs
    INNER JOIN tbl_Courses c ON cs.CourseID = c.CourseID
    INNER JOIN tbl_Users u ON cs.UserID = u.UserID
    WHERE Student = 1 AND cs.CourseID = @CourseID
   
    RETURN @@ROWCOUNT
GO
CREATE PROCEDURE StudentAnswer_Set @UserID int, @QuestionID int, @ChoiceID int
AS
    SET NOCOUNT ON
   
    if not exists(select 1 from dbo.tbl_Responses
                    where UserID = @UserID AND QuestionID = @QuestionID)
                   
                insert into dbo.tbl_Responses
                    (UserID, QuestionID, ChoiceID)
                values
                    (@UserID, @QuestionID, @ChoiceID)
    else
            UPDATE dbo.tbl_Responses
            SET ChoiceID = @ChoiceID
            WHERE UserID = @UserID AND QuestionID = @QuestionID

    RETURN 0
   
    RETURN @@ROWCOUNT
GO
CREATE PROCEDURE StudentQuizResponses_Get
   
    @UserID int,
    @QuizID int
AS
    DECLARE @Name varchar(20)
   
    SELECT @Name = Name
    FROM tbl_Users
    WHERE UserID = @UserID
   
    SELECT
        c.Course,
        z.QuizID,
        z.Quiz
        FROM tbl_Quizes z
        INNER JOIN tbl_Courses c on z.CourseID = c.CourseID
        WHERE z.QuizID = @QuizID

    SELECT
         u.UserID,
         u.Name,
         q.QuestionID,
         q.Question,
         c.Choice AS [Student Choice],
         [Correct Choice] = (SELECT Choice
                            FROM tbl_Choices
                            WHERE QuestionID = q.QuestionID
                                AND Correct = 1),
          CASE WHEN r.ChoiceID = (SELECT ChoiceID
                        FROM tbl_Choices
                        WHERE QuestionID = q.QuestionID
                            AND Correct = 1)
             THEN (SELECT [Points]
                        FROM tbl_Questions
                        WHERE QuestionID = q.QuestionID    )
            ELSE 0
           
            END AS [Points]
         
    FROM
         tbl_Users u INNER JOIN
         tbl_Responses r ON r.UserID = u.UserID
         INNER JOIN tbl_Questions q ON q.QuestionID = r.QuestionID
         INNER JOIN tbl_Choices c ON c.ChoiceID = r.ChoiceID
    WHERE u.UserID = @UserID AND QuizID = @QuizID
   
    UNION
   
    SELECT
        @UserID,
        @Name,
        q.QuestionID,
        q.Question,
        '',
        Choice,
        0
    FROM
        tbl_Questions q
        INNER JOIN tbl_Choices c ON c.QuestionID = q.QuestionID
        INNER JOIN tbl_Quizes z ON q.QuizID = z.QuizID
        WHERE c.Correct=1
                AND z.QuizID = @QuizID
                AND c.QuestionID NOT IN (
                                    SELECT q.QuestionID
                                    FROM tbl_Questions q
                                    LEFT OUTER JOIN tbl_Responses r ON r.QuestionID = q.QuestionID
                                    WHERE QuizID = @QuizID AND UserID = @UserID)
    RETURN 0
GO

DECLARE
    @CourseID int,
    @QuizID int,
    @QuestionID int,
    @ChoiceID int,
    @Show bit = 1

INSERT tbl_Users (Name)
    VALUES ('Pascal'), ('Bernoulli'), ('Arostitle'), ('Heinz Ketchupberg'), ('Fritz Rommel'),
    ('Abdul'), ('Achmed'), ('Sadik'), ('Machmoud')

INSERT [tbl_Courses] (Course)
    SELECT 'Koranic Studies';
   
SET @CourseID = SCOPE_IDENTITY()

INSERT into tbl_CourseStudents (UserID, CourseID)
    VALUES
    (225, @CourseID),
    (227, @CourseID),
    (228, @CourseID),   
    (229, @CourseID),
    (230, @CourseID)

-- Sadik is the Professor
UPDATE tbl_Users SET Teacher=1, Student=0 WHERE UserID = 229

IF (@Show = 1)
EXEC StudentsInCourse @CourseID
   
INSERT [tbl_Courses] (Course)
    SELECT 'German';
   
SET @CourseID = SCOPE_IDENTITY()

INSERT into tbl_CourseStudents (UserID, CourseID)
    VALUES
    (225, @CourseID),
    (226, @CourseID)

IF (@Show = 1)   
EXEC StudentsInCourse @CourseID

INSERT [tbl_Quizes]
    ([CourseID], [Quiz])
        VALUES
     (@CourseID, 'Pop Quiz 1: Accusative, Nomative, Dative')

SET @QuizID = SCOPE_IDENTITY()

INSERT [tbl_Questions]
    ( [QuizID], [Question], Points )
        VALUES
    ( @QuizID, 'Wie heißt du?', 1)

INSERT [tbl_Questions]
    ( [QuizID], Question, [Points] )
        VALUES
    ( @QuizID, 'Ich bin ein __________', 1)

INSERT [tbl_Questions]
    ( [QuizID], [Question], [Points] )
        VALUES
    ( @QuizID, 'Does an Audi or Porsche handle best?', 5)
   
INSERT [tbl_Courses] (Course)
    SELECT 'Algebra'; SET @CourseID = SCOPE_IDENTITY()

INSERT into tbl_CourseStudents (UserID, CourseID)
    VALUES
    (222, @CourseID),
    (223, @CourseID),
    (224, @CourseID)

IF (@Show = 1)
EXEC StudentsInCourse @CourseID
   
INSERT [tbl_Quizes]
    ([CourseID], [Quiz])
        VALUES
     (@CourseID, 'Test 1: Reciprocals and Squares')
     
SET @QuizID = SCOPE_IDENTITY()   

IF (@Show = 1)
SELECT c.CourseID, q.QuizID, q.Quiz
FROM tbl_Quizes q
    INNER JOIN tbl_Courses c
    ON q.CourseID = c.CourseID
    WHERE QuizID = @QuizID
 
INSERT [tbl_Questions]
    ( [QuizID], [Question], Points )
        VALUES
    ( @QuizID, 'What is the square root of 81?', 5)

SET @QuestionID = SCOPE_IDENTITY()

IF (@Show = 1)
SELECT c.CourseID, q.QuizID, ask.QuestionID, ask.Question, ask.Points
FROM tbl_Quizes q
    INNER JOIN tbl_Courses c
    ON q.CourseID = c.CourseID
    INNER JOIN tbl_Questions ask
    ON q.QuizID = ask.QuizID
    WHERE q.CourseID = @CourseID


-- use HTML superscript tag <sup> to indicate squared
INSERT INTO tbl_Choices
    ( [QuestionID], [Choice] )
        VALUES
    (@QuestionID, '3<sup>2</sup>' )

INSERT INTO tbl_Choices
    ( QuestionID, [Choice] )
        VALUES
    (@QuestionID, '9')

INSERT INTO tbl_Choices
    ( QuestionID, [Choice] )
        VALUES
    (@QuestionID, '1/3 x 3<sup>3</sup>')

INSERT INTO tbl_Choices
    ( QuestionID, [Choice], [Correct] )
        VALUES
    (@QuestionID, 'All of the Above', 1)

INSERT INTO tbl_Choices
    ( QuestionID, [Choice], [Correct] )
        VALUES
    (@QuestionID, 'None of the Above', 0)

IF (@Show = 1)
SELECT c.CourseID, q.QuizID, ask.QuestionID, which.ChoiceID, which.Choice, which.Correct
FROM tbl_Quizes q
    INNER JOIN tbl_Courses c
    ON q.CourseID = c.CourseID
    INNER JOIN tbl_Questions ask
    ON q.QuizID = ask.QuizID
    INNER JOIN tbl_Choices which
    ON ask.QuestionID = which.QuestionID   

INSERT [tbl_Questions]
    ( [QuizID], [Question], [Points] )
        VALUES
    ( @QuizID, 'What is the reciprocal of one-half?', 5)

SET @QuestionID = SCOPE_IDENTITY()

IF (@Show = 1)
SELECT c.CourseID, q.QuizID, ask.QuestionID, ask.Question
FROM tbl_Quizes q
    INNER JOIN tbl_Courses c
    ON q.CourseID = c.CourseID
    INNER JOIN tbl_Questions ask
    ON q.QuizID = ask.QuizID
    WHERE QuestionID = @QuestionID


    INSERT INTO tbl_Choices
        ( QuestionID, [Choice] )
            VALUES
        (@QuestionID, '1/4')

    INSERT INTO tbl_Choices
        ( QuestionID, [Choice], [Correct] )
            VALUES
        (@QuestionID, '2', 1)

    INSERT INTO tbl_Choices
        ( [QuestionID], Choice )
            VALUES
        (@QuestionID, '4')

    INSERT INTO tbl_Choices
        ( QuestionID, [Choice], Correct )
            VALUES
        (@QuestionID, 'None of the Above', NULL)

IF (@Show = 1)
SELECT c.CourseID, q.QuizID, ask.QuestionID, which.ChoiceID, which.Choice, which.Correct
FROM tbl_Quizes q
    INNER JOIN tbl_Courses c
    ON q.CourseID = c.CourseID
    INNER JOIN tbl_Questions ask
    ON q.QuizID = ask.QuizID
    INNER JOIN tbl_Choices which
    ON ask.QuestionID = which.QuestionID
    WHERE ask.QuestionID = @QuestionID


/* Use AJAX to Asynchronously Post Choice Selected to database */
-- Here Pascal (UserID = 222)
-- answers the Square Root of 81 (QuestionID = 55558)
-- with Choice All of the Above (ChoiceID = 4)
EXEC StudentAnswer_Set @UserID = 222, @QuestionID = 55558, @ChoiceID = 666669
-- reciprocal of 1/2
EXEC StudentAnswer_Set @UserID = 222, @QuestionID = 55559, @ChoiceID = 666672
-- show test results
EXEC StudentQuizResponses_Get @UserID = 222, @QuizID = 4445

--Bernoulli
EXEC StudentAnswer_Set @UserID = 223, @QuestionID = 55559, @ChoiceID = 666671
EXEC StudentQuizResponses_Get @UserID = 223, @QuizID = 4445

GO
DROP TABLE dbo.tbl_Responses
GO
DROP TABLE dbo.tbl_Choices
GO
DROP TABLE dbo.tbl_Questions
GO
DROP TABLE dbo.tbl_Quizes
GO
DROP TABLE tbl_CourseStudents
GO
DROP TABLE dbo.tbl_Users
GO
DROP TABLE dbo.tbl_Courses
GO
DROP PROCEDURE dbo.StudentsInCourse
GO
DROP PROCEDURE dbo.StudentAnswer_Set
GO
DROP PROCEDURE StudentQuizResponses_Get



MVC3 Entity Framework To infer primary key, or not to infer --or exclude altogether in Model1.edmx

The table/view 'dbo.Pets' does not have a primary key defined.
The key has been inferred and the definition was created as a read-only table/view.

The table/view 'dbo.WebPaymentGatewayLog' does not have a primary key defined and no valid primary key could be inferred. This table/view has been excluded. To use the entity, you will need to review your schema, add the correct keys, and uncomment it. 
The data type 'geography' is not supported; the column 'GEOG' in table 'dbo.World_Cities' was excluded. c:\users\BigHoss\documents\visual studio 2010\Projects\Mvc3App02\Mvc3App02\Model1.edmx

Tuesday, October 25, 2011

Maintaining Scroll Position on Postback

Don't you hate it when you're trying to solve a problem and you find old answers to problems that have since been solved for you? Well, almost solved --or more betterer solved than before. 

http://www.4guysfromrolla.com/articles/111704-1.aspx presents problems with <%@ Page SmartNavigation="true" %> and gives Javascript examples with hidden fields.  This was a version 1.0 problem, since deprecated.  

Microsoft fixed it with  Page.SetFocus and Page.MaintainScrollPositionOnPostBack. Still, trying to set the focus on a field within a templated control or within a named container  requires you to either understand the control hierarchy, or use a recursion method that acts like a squirrel running up and down a tree and back and forth on each branch looking for his nuts.  

Things get complicated when using a Master Page and children Pages --more later


T-SQL Transaction Terminate

EXEC Sp_who2;
KILL SPID

ASP.NET Controls LifeCycle, Themes, Browser Detection

 Microsoft Developers Network (MSDN) ASP.NET Page Lifecycle  The master page doesn't have a Pre_Init phase.

Sunday, October 23, 2011

CodeBehind, CodeFile, Inline Code Snippet <%@ Import Namespace="System.Threading" %>

<%@ Import Namespace="System.Threading" %> 

Use inline when no public partial class MyCompanies : System.Web.UI.Page class definition in a CodeFile/CodeBehind


<%@ Page Language="C#" Title="EzPL8 - Relate by Plate: Investigate, Date, Communicate" uiculture="auto" EnableViewState="false"  EnableSessionState="False" MasterPageFile="~/Site.master"%>

<%@ Import Namespace="System.Threading" %>

<%@ Import Namespace="System.Globalization" %>

<%@ Import Namespace="System.Collections.Generic" %>


CodeBehind & CodeFile are a little cleaner with no <%, import, namespace, or quotes --just use using .


The difference between the two:

Behind leaves the source behind: it's compiled, with the DLL placed in the bin folder .

File is the source --for a partial class



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MyCompanies.aspx.cs" Inherits="MyCompanies" EnableEventValidation="false" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>

<script runat="server">


In the MyCompanies.aspx.cs file

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using AjaxControlToolkit;


public partial class MyCompanies : System.Web.UI.Page

{

    bool FilterSearch = false;

    bool FilterCategory = false;


// get elementID for jQuery autocomplete lookup

    protected string GetClientIDforCoID() { return this.dvAccount.FindControl("CoID").ClientID.ToString(); }


// getElementId from DetailsView for jQuery autocomplete lookup

// from a PageMethod; XML or JSON from .asmx/.svc; or JSONP from your own.ashx 

// or other web services provider.


    protected string GetClientIDforCompany() { 

        if (this.dvAccount.FindControl("Company") != null)

            return this.dvAccount.FindControl("Company").ClientID.ToString(); 

        else return string.Empty;

    }


    protected void Page_Load(object sender, EventArgs e)

    {

        if (!IsPostBack)

        {

            if (!Context.User.Identity.IsAuthenticated)

                Server.Transfer("~/Account/Login.aspx?ReturnURL=..%2fCompanies.aspx");


            //omb.Hide(); do this in gvAccounts DataBound

             //dvAccount.Visible = false; //replaceme  do this in gvAccounts DataBound

        }

    }

}

Host Tracker Alerts - Get an Email When Web Site Down

From: HostTracker Notifier <noreply-www@host-tracker.com>
Date: Sun, Oct 23, 2011 at 9:11 PM
Subject: HostTracker alert! EzPL8 KeepAlive - 1x1.gif down

Hello,

 [EzPL8 KeepAlive - 1x1.gif] http://www.ezpl8.com/KeepAlive.aspx is down

Error was detected at 2011-10-23 09:10:14 PM:

       Milano, Italy, Lombardia - RequestCanceled (6)
       Maidenhead, United Kingdom - RequestCanceled (6)
       Kyiv, Ukraine - RequestCanceled (6)
       Amsterdam, Netherlands - RequestCanceled (6)
       Amsterdam, Netherlands - RequestCanceled (6)
       Kyiv, Ukraine - RequestCanceled (6)

Incident details: http://www.host-tracker.com/Event/IncidentView/2be8d6ea-dcfd-e011-bc01-f4ce46998348
--
Best regards,
http://host-tracker.com support team





GoDaddy Site Analytics, User History, Log Parser, Hit Counter Example Tutorial


For $2.99 a month GoDaddy.com provides Site Analytics, which reads your Microsoft web server's IIS log files and summarizes your hit counter along with IP addresses for you similar to WebTrends

You can do this yourself with open source and free code if you have Admin rights to your server, i.e. you can configure request logging in IIS Manager.

Then use Log Parser  to read XML, tab and space separated files, active directory, Windows registry, and Netmon captures. Output as charts, text, or send to a SYSLOG server.

Because you don't have access to the log files at GoDaddy, some useful tools such as Microsoft's Log Parser and Apache Log4Net are of limited use.

Output - slowest pages

Log Parser does charts.
Output - most commonly used .aspx
		  pages

  Download the Apache Software Foundation port of Log4j for C# for ASP.Net at http://logging.apache.org/log4net/download.html


W3SVC Extended Log Format fields:
date
time 
s-sitename 
s-ip
cs-method 
cs-uri-stem 
cs-uri-query
s-port
cs-username 
c-ip
cs(User-Agent) 
sc-status 
sc-substatus 


sc-win32-status

Unfortunately, in the free, shared hosting plans you don't have access to the log files for a number of reasons. However, if you did, you could use code snippets from http://www.mikesdotnetting.com/Article/103/Build-your-own-Whois-Lookup-with-ASP.NET-and-jQuery :


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="IPLookup.aspx.cs" Inherits="IPLookup" %>

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Untitled Pagetitle>
    <style type="text/css">
        body { font-family:Verdana;font-size:76%; }
        pre { font-size:10pt; }
        span { cursor:pointer; }
        #dns { float:left; }
        #calendar{ float:left;width:350px; }
        #loading { left:300px;z-index:100;position:absolute; }
    style>
head> 
<body> 
     id="form1" runat="server">

    <div id="calendar">
      <asp:Calendar ID="Calendar1" runat="server"
        onselectionchanged="Calendar1_SelectionChanged" />
      <asp:Literal ID="ip_addresses" runat="server" />
    div>
    <div id="dns">div>
    <div id="loading">div>
    form>
body> 
html> 


protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
    ip_addresses.Text = "";
    List<string> IPs = new List<string>();
    StringBuilder sb = new StringBuilder();
    DateTime date = Calendar1.SelectedDate;
    string filedate = string.Format("{0:yyMMdd}", date);
    string path = @"D:\Logs\ex" + filedate + ".log";

    if (File.Exists(path))
    {
        string content;
        using (StreamReader sr = new StreamReader(path))
        {
            content = sr.ReadToEnd();
        }

        Regex re = new Regex(@"\w\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}\w");
        MatchCollection mc = re.Matches(content);
        foreach (Match mt in mc)
        {
            if (mt.ToString() != "xxx.xxx.xxx.xxx")
                IPs.Add(mt.ToString());
        }

        var result = IPs.Select(i => i).Distinct().ToList();

        foreach (string ip in result)
        {
            sb.Append("" + ip + "\n");
        }

        ip_addresses.Text = "
" + sb.ToString() + "

";

    }
    else
    {
        ip_addresses.Text = "No logs available for that date";
    }
}
private static string GetHtmlPage(string url)
{
    String result;
    WebResponse response;
    WebRequest request = HttpWebRequest.Create(url);
    response = request.GetResponse();
    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
    {
        result = sr.ReadToEnd();
        sr.Close();
    }
    return result;
}
private static string PostHtmlPage(string url, string post)
{
    ASCIIEncoding enc = new ASCIIEncoding();
    byte[] data = enc.GetBytes(post);
    WebRequest request = HttpWebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    Stream stream = request.GetRequestStream();
    stream.Write(data, 0, data.Length);
    stream.Close();
    WebResponse response = request.GetResponse();
    string result;
    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
    {
        result = sr.ReadToEnd();
        sr.Close();
    }
    return result;
}
[WebMethod]
public static string GetWhois(string ip)
{
    string response = "";
    string arin = "https://ws.arin.net/whois/?queryinput=" + ip;
    string ripe = "http://www.db.ripe.net/whois?form_type=simple&full_query_string=&searchtext=" + ip + "&do_search=Search";
    string apnic = "http://wq.apnic.net/apnic-bin/whois.pl";
    string lacnicFields = "query=" + ip;
    string apnicFields = ".cgifields=object_type&.cgifields=reverse_delegation_domains&do_search=Search&" +
                         "form_type=advancedfull_query_string=&inverse_attributes=None&object_type=All&searchtext=" + ip;
    response = GetHtmlPage(arin);
    Regex pre = new Regex(@"
[.\n\W\w]*</p>", RegexOptions.IgnoreCase);

    Match m = pre.Match(response);
    if (pre.IsMatch(response))
    {
        if (m.Value.IndexOf("OrgName:    RIPE Network Coordination Centre") > 0)
        {
            response = GetHtmlPage(ripe);
            m = pre.Match(response);
        }
        else if (m.Value.IndexOf("OrgName:    Asia Pacific Network Information Centre") > 0)
        {
            response = PostHtmlPage(apnic, apnicFields);
            m = pre.Match(response);
        }
        else if (m.Value.IndexOf("OrgName:    Latin American and Caribbean IP address Regional Registry") > 0)
        {
            response = PostHtmlPage(lacnic, lacnicFields);
            m = pre.Match(response);
        }
        return m.Value;
    }
    else
    {
        return "
No Data

";

    }
}
<script type="text/javascript" src="script/jquery-1.3.2.min.js">script> 
<script type="text/javascript"
  $(document).ready(function() {
    $("span").each(function() {
      $(this).click(function() {
        $("#loading").html("");
        $("#dns").empty();
        $.ajax({
          type: "POST",
          contentType: "application/json; charset=utf-8",
          data: "{ip: '" + $(this).html() + "'}",
          url: "IPLookup.aspx/GetWhois",
          dataType: "json",
          success: function(response) {
            $("#loading").empty();
            $("#dns").html(response.d);
          }
        });
      });
    });
  });
script> 

Thursday, October 06, 2011

Add Skip and Take parameters along with ROW_NUMBER to Stored Procedures for Paginating

The example below is based on what Linq automagically does for you when it dynamically constructs a T-SQL statement.

Three new aspects for paging, compared to a normal query, include.

  1. Add the command ROW_NUMBER() OVER(ORDER BY SomeColumn[s]) to your query to get an ordered index of records the way you want them 
    • the down side is you cannot sort by different columns in your app.
  2. Give that query an alias/name, [InsideQuery] in my example below (this won't work if you don't, even though the alias is never used), and wrap it with a SELECT * FROM, a succint way of creating a temporary table without having to create a temporary table as suggested in older examples.
  3. Now you can use the Row Number BETWEEN statment on the outer select --Row Number wasn't available on the inside select statement to perform the BETWEEN, but it is on the outside...
 DECLARE @Skip int = 0 	, @Take int = 5  SELECT * FROM	( 				SELECT ROW_NUMBER() OVER(ORDER BY Company) AS [RowNum], CoID, Company, CompanyURL  				FROM ezpl8_Companies  			) AS [InsideQuery]

WHERE [RowNum] BETWEEN (@Skip * @Take) + 1 AND (@Skip + 1) * @Take


Wednesday, June 15, 2011


Hit Counter for Logging Users with ASP.net and SQL Server when you don't have access to Windows Server IIS Log Files from Shared/Free Hosting

T-SQL Table for persistent storage and Stored Procedure to save visitor info


SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Log](
LogID int not null identity(1,1) CONSTRAINT PK_Log PRIMARY KEY ([LogID]) ,
[Created] [datetime] NOT NULL  ,
[Page] [varchar](255) NOT NULL,
[UserAgent] [varchar](255) NULL,
[IP] [varchar](15) NULL,  --IPv4 only
[Referrer] [varchar](max) NULL,
[LangCult] [varchar](5) NULL
) ON [PRIMARY]

GO

ALTER PROCEDURE LogCreate
@Created smalldatetime,
@Page varchar(255) = null ,
@UserAgent varchar(255) = null,
@IP varchar(15) = null,
@Referrer varchar(max) = null,
@LangCult varchar(5) = null
AS
BEGIN
INSERT INTO my_Log
(Created, Page, UserAgent, IP, Referrer, [LangCult])
VALUES
(@Created, @Page, @UserAgent, @IP, @Referrer, @LangCult)

RETURN 0
END
GO


C#  This code is called by other pages using  <img src="http://www.YourSite.com/KeepAlive.aspx" height="0" width="0" />

<%@ import namespace="System.Web"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    public void Page_Load(object sender, EventArgs e)
    {
        // to encrypt a connection string in web.config:  aspnet_regiis -pe "connectionStrings" -app "/MyWebsite" -prov "DataProtectionConfigurationProvider"

        string strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["myConnectionStringfromWebConfig"].ConnectionString;

        if (strConnString != null)
        {
            using (SqlConnection cn = new SqlConnection(strConnString))
            {
                using (SqlCommand cmd = new SqlCommand("LogCreate", cn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("@Created", SqlDbType.SmallDateTime).Value = DateTime.Now;
                    cmd.Parameters.Add("@Page", SqlDbType.VarChar).Value = this.Request.Url.AbsolutePath;  //Request.CurrentExecutionFilePath)
                    cmd.Parameters.Add("@UserAgent", SqlDbType.VarChar).Value = this.Request.UserAgent;
                    cmd.Parameters.Add("@IP", SqlDbType.VarChar).Value = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

                    string sReferrer = string.Empty;
                    if (Request.UrlReferrer != null) sReferrer = Request.UrlReferrer.ToString();
                    cmd.Parameters.Add("@Referrer", SqlDbType.VarChar).Value = sReferrer;
                 
                    string sUserLanguage = string.Empty;
                    if (Request.UserLanguages[0] != null) sUserLanguage = Request.UserLanguages[0];
                    cmd.Parameters.Add("@LangCult", SqlDbType.VarChar).Value = sUserLanguage;
                 
                    cn.Open();
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }

This'll get you started to view the log.  There's no filtering so if your site experiences a DDOS attack, each page hit will be recorded, making your SQL Server MDF file grow rapidly. 

<%@ import namespace="System.Web"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    public void Page_Load(object sender, EventArgs e)
    {
        // to encrypt a connection string in web.config:  aspnet_regiis -pe "connectionStrings" -app "/MyWebsite" -prov "DataProtectionConfigurationProvider"

        string strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["myConnectionStringfromWebConfig"].ConnectionString;

        if (strConnString != null)
        {
            using (SqlConnection cn = new SqlConnection(strConnString))
            {
                using (SqlCommand cmd = new SqlCommand("LogCreate", cn))
                {

                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "SELECT DISTINCT  ISNULL([LangCult],'') AS [LangCult], [IP], [UserAgent], ISNULL([Referrer],'') AS [Referrer] FROM [ezpl8_Log]";
                 
                    // SqlDataReader is fast-forward, read only
                    SqlDataReader myReader = cmd.ExecuteReader();
                    if (myReader.Read())
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendFormat("<table style=\"font-size:{0}pt;font-family:arial;\">", "8");
                     
                        do
                        {
                            while (myReader.Read())
                                sb.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", myReader.GetString(0), myReader.GetString(1), myReader.GetString(2), myReader.GetString(3));
                        } while (myReader.NextResult());

                        sb.AppendFormat("</table>");
                        Response.Write(sb.ToString()); ;
                    }

                }
            }
        }
    }



Young Roofers

Young Roofers
Men Making

Fly. Be Free.

Fly. Be Free.
Man Ready to Hang ... Glide

Burke

Burke
A Man in the Making - 12 years old

Blackwater

Blackwater
A Man in the Mud