Thursday, December 1, 2011

SQUID: การตั้ง proxy บล็อคเว็บไซต์ตามช่วงเวลาที่กำหนด

Squid สามารถบล็อคเว็บไซต์เป็นบางวัน บางช่วงเวลาตามที่เราต้องการได้ วิธีการมี 2 ขั้นตอนด้วยกัน

1. สร้างไฟล์ใส่ชื่อเว็บที่ต้องการ เป็น text file ธรรมดา

vi myblockweb


สมมุติจะบล็อค facebook กับ pantip ข้างในไฟล์ myblockweb ก็พิมพ์

facebook.com
pantip.com


แล้วก็ save

2. แก้ไฟล์ squid.conf (ปกติก็อยู่ใน /etc/squid) ค้นหาบรรทัด bsex แล้วแก้ไขคำสั่งการ Blockweb ใหม่ ดังนี้

#blockweb จันทร์-ศุกร์ บล็อคช่วงเวลา 08.30 - 12.00 น. และ  13.00 - 17.30 น.
acl time_block time M T W H F 08:30-12:00
acl time_block time M T W H F 13:00-17:30

#blockweb เสาร์ ช่วงเวลา 09.00 - 12.00 น. และ 13.00 - 17.00 น.
acl time_block time A 09:00-12:00
acl time_block time A 13:00-17:00

# บล็อคเว็บที่อยู่ในไฟล์ myblockweb
acl bsex url_regex "myblockweb"
http_access deny bsex time_block
deny_info http://www.mycompany.com/deny.htm bsex time_block


M T W H F คือวัน จันทร์ อังคาร พุธ พฤหัส ศุกร์
A คือวันเสาร์
ถ้าจะบล็อควันอาทิตย์ด้วยก็เพิ่มตัว S ไปหลัง time
ตรงที่เป็น http://www.mycompany.com/deny.htm คือให้เด้งไปที่หน้านี้ ถ้ามีคนเข้าเว็บที่เราบล็อค

Saturday, October 1, 2011

C#: There is already an open DataReader associated with this Command which must be closed first

เมื่อคุณเจอ error: There is already an open DataReader associated with this Command which must be closed first.
เช่นตอนวนลูป while ตัวอย่างเช่น

ConnectionStringSettings connSettings = ConfigurationManager.ConnectionStrings["MyConnectionString"];
string connString = connSettings.ConnectionString;
SqlConnection conn = new SqlConnection(connString);

string strSQL = "SELECT * FROM MyTable1 WHERE DelFlag=1";
SqlCommand cmd = new SqlCommand(strSQL, conn);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string strSQL2 = "UPDATE MyTable2 SET DelFlag=1 WHERE RefId = '" + reader["Id"].ToString() + "'";
SqlCommand cmd2 = new SqlCommand(strSQL2, conn);
cmd2.ExecuteNonQuery();
cmd2.Dispose();
}
reader.close();
cmd.Dispose();


run ไปจะเจอ error นี้


วิธีแก้


ดูตรงเปิด connection ด้านบน

SqlConnection conn = new SqlConnection(connString);

ให้เพิ่ม MultipleActiveResultSets=True ลงไป เป็น


SqlConnection conn = new SqlConnection(connString + "MultipleActiveResultSets=True");

แค่นี้ก็เรียบร้อย

Thursday, September 1, 2011

C#: ไม่มีไฟล์ App.config

ถ้าคุณสร้างโปรเจ็คต์ Windows Form ใหม่ แล้วไม่มีไฟล์ App.config เพื่อใส่ค่า Configuration ต่างๆ เช่น ConnectionString ก็สามารถใส่ไฟล์ App.config ได้โดยการ

  1. คลิกขวาที่ชื่โปรเจ็คต์ เลือ Properties
  2. คลิกที่แท็บ Settings แล้วตรง Name กรอกอะไรเล่นๆสักค่าหนึ่ง ตรง Value ก็กรอกเล่นๆ
  3. Save แล้วลองรันโปรแกรมดู 
ทีนี้ไฟล์ App.config ก็จะโผล่มาใน Solution Explorer ให้คุณแก้ค่าได้ตามปกติ

Monday, August 1, 2011

SQL Server: RowNumber หมายเลขบรรทัดอัตโนมัติ

ถ้าเราต้องการจะแทรกหมายเลขบรรทัดอัตโนมัติ

SELECT ROW_NUMBER() OVER (ORDER BY StudentId DESC) AS RowNumber, * FROM Student


วิธีนี้สามารถเอาไปใช้ในการทำ paging หรือการแบ่งหน้าได้ เช่นถ้าเราต้องการ select เฉพาะรายการที่ 1000 ถึง 1100

with X as (SELECT ROW_NUMBER() OVER (ORDER BY StudentId DESC) AS RowNumber, * FROM Student)
select top 100 * from X where RowNumber >= 10000

Friday, July 1, 2011

MySQL: ย้าย Table ไป Database อื่น ใน Server เดียวกัน

ใช้คำสั่ง rename

สมมุติว่าจะย้ายตารางชื่อ tbl_name จาก database ชื่อ current_db ไปยัง other_db

RENAME TABLE current_db.tbl_name TO other_db.tbl_name;

บรรทัดเดียวเสร็จ ไม่ว่าจะเข้าทาง command line หรือใช้ phpMyAdmin

หรือถ้าคุณไม่อยากย้าย แต่อยากจะ copy คือจะสร้าง table ใหม่ให้เหมือน table เดิมเป็น และ table เดิมยังอยู่ ก็ใช้

CREATE TABLE MyNewTable SELECT * FROM MyOldTable;

ก็จะได้ table ใหม่ชื่อ MyNewTable ที่มีโครงสร้างและข้อมูลเหมือน MyOldTable เป๊ะ ถ้าจะ copy table ข้าม database ด้วย ก็ใส่ชื่อ database. ข้างหน้าชื่อ table

ข้อควรระวัง วิธีนี้พวก Index หรือ Primary Key และพวก Auto_Increment ที่ตั้งไว้ใน table ต้นทางจะไม่ตามไปด้วย เราต้องทำเพิ่มใน table ปลายทางเอง ทางที่ดีควรจะสร้างสคริปต์ Create Table ไปสร้างใน database ใหม่ แล้วค่อยใช้คำสั่งย้ายข้อมูลคือ

INSERT INTO NewDB.NewTable SELECT * FROM OldDB.OldTable

Wednesday, June 1, 2011

SQL Server: การ join ข้าม database

เวลาคุณจะ join ตารางที่อยู่คนละ database หรือจะเพิ่มข้อมูลใน database หนึ่ง โดยการ select มาจากอีก database หนึ่ง ไม่ใช่ว่าอยู่ดีๆคุณก็จะทำได้ รายชื่อ table ที่คุณสามารถ join กัน หรือ select ร่วมกันได้จะอยู่ใน sys.servers ลอง

select * from sys.servers

ถ้ามีชื่อ server ที่คุณจะ join อยู่ในนี้ก็แสดงว่า join ได้ คำสั่งในการ join ก็เช่น

SELECT TOP 20 * FROM [MyServer1].[DBTest].[dbo].[Product] a 
INNER JOIN [MyServer2].[DBReal].[dbo].[Products] b ON a.code = b.code

การที่จะทำให้ MyServer1 กับ MyServer2 join กันได้ตามคำสั่งด้านบน คุณต้องเพิ่มชื่อ server ใน sys.servers เสียก่อน ถ้าคุณ log in ใช้ MyServer1 อยู่ ก็ run คำสั่งต่อไปนี้

EXEC sp_addlinkedserver @server='MyServer2' 

แล้วก็ต้องเพิ่ม user ที่ใช้ในการ log in เข้า MyServer2 ด้วย

EXEC master.dbo.sp_addlinkedsrvlogin  @rmtsrvname=N'MyServer2',  
@useself=N'False',
@locallogin=NULL,
@rmtuser=N'mydbuser',
@rmtpassword='mypassword'
GO

แค่นี้ก็เรียบร้อย

Sunday, May 1, 2011

IIS: The requested page cannot be accessed because the related configuration data for the page is invalid

เมื่อคุณเจอ Error

HTTP Error 500.19 - Internal Server Error

The requested page cannot be accessed because the related configuration data for the page is invalid.

ซึ่งเกิดขึ้นหลังจากที่คุณเปลี่ยน password ในการ log on เข้า windows
วิธีแก้ก็คือ
  • เปิด IIS (อยู่ใน Control Panel -> Administration Tools)
  • คลิกที่ Default Website
  • ด้านขวาจะมี Basic Settings คลิกเข้าไป
  • คลิกปุ่ม Connection as ใส่ username และ Password ใหม่ของคุณเข้าไป
แล้วก็ restart IIS ก็จะรันได้ตามปกติ
แต่ถ้า restart IIS แล้วยังเจอ error

HTTP Error 401.2 - Unauthorized

You are not authorized to view this page due to invalid authentication headers.

ให้ reatart Application Pools ด้วย

Friday, April 1, 2011

C#: การอ่านไฟล์ Excel

ถ้าเป็นไฟล์ excel เวอร์ชั่นเก่าที่เป็นนามสกุล .xls ให้อ่านด้วย Microsoft.Jet.OLEDB.4.0 แต่ถ้าเป็นเวอร์ชั่นใหม่ .xlsx ต้องใช้ Microsoft.ACE.OLEDB.12.0

HDR=YES คือไฟล์นั้นมีแถวที่เป็น Header
IMEX=1 เกี่ยวกับการ Encoding ภาษาให้ถูกต้อง


string filePath = @"C:\temp\test.xls";
DataSet objDataset1 = new DataSet();
string ConnectionString = "";
ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
if (filePath.IndexOf("xlsx") != -1) // ถ้าเป็น excel เวอร์ชั่นใหม่
{
ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
}

OleDbConnection objXlsConn = new OleDbConnection(ConnectionString);
objXlsConn.Open();
OleDbDataAdapter objAdapter1 = null;
OleDbCommand objCmdSelect = null;
try
{
// หาชื่อ worksheet.
System.Data.DataTable dt = objXlsConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
DataRow row = dt.Rows[0];
string worksheetName = row["TABLE_NAME"].ToString();

// อ่านทุกแถวใน worksheet ด้วยคำสั่ง SQL
String strConString = "SELECT * from [" + worksheetName + "]";
objCmdSelect = new OleDbCommand(strConString, objXlsConn);
objAdapter1 = new OleDbDataAdapter(objCmdSelect);
objAdapter1.Fill(objDataset1);

// ตั้งตัวแปรสำหรับรับค่าในคอลัมน์
string dataColumn1;
string dataColumn2;

// วนลูปอ่านทีละแถว
foreach (DataRow dr in objDataset1.Tables[0].Rows)
{
dataColumn1 = dr[0].ToString();
dataColumn2 = dr[1].ToString();
// อยากทำอะไรต่อกับค่าที่ได้ก็เขียนตรงนี้
}
}
catch (Exception ex)
{
var strMsg = ex.Message;
// จะทำอะไรกับ error message ก็ทำตรงนี้
}


จะเห็นได้ว่าเราสามารถใช้คำสั่ง SQL กับ worksheet ของ Excel ได้ ทีนี้ในการ Insert, Update, Delete เราก็สามารถทำได้เหมือนกัน

Tuesday, March 1, 2011

JavaScript: วันที่วันพรุ่งนี้

var myDate = new Date(); จะได้วันที่ของวันนี้
ถ้าต้องการวันที่ของวันพรุ่งนี้ หรือล่วงหน้า หรือย้อนหลังไปกี่วันเราก็อาศัยคำสั่ง getDate() บวกหรือลบวันเอา
เช่นวันที่ของวันพรุ่งนี้

var myDate = new Date();
var myTomorrow = myDate.setDate(myDate.getDate()+1);

วันที่ของเมื่อวานนี้
var myYesterday = myDate.setDate(myDate.getDate()-1);

วันที่ของสัปดาห์หน้า
var myNextWeek = myDate.setDate(myDate.getDate()+7);

คำสั่ง getDate() จะได้วันที่ออกมา ถ้าบวก 1 แล้วได้ 32 หรือเกินวันที่จริงของเดือนนั้น มันก็จะปัดไปเป็นวันที่ของเดือนถัดไปอัตโนมัติ

Tuesday, February 1, 2011

SQL Server: sp_rename เปลี่ยนชื่อฟิลด์

ใช้ sp_rename 'ชื่อตาราง.ชื่อฟิลด์เก่า', 'ชื่อฟิลด์ใหม่', 'COLUMN'

ตัวอย่างเช่น

sp_RENAME 'Customer.DocNo', 'RefNo', 'COLUMN'


คือการเปลี่ยนชื่อฟิลด์ในตาราง Customer จาก DocNo ให้เป็น RefNo

ถ้า result ขึ้นว่า

Caution: Changing any part of an object name could break scripts and stored procedures.


แสดงว่าเปลี่ยนชื่อสำเร็จแล้ว

Saturday, January 1, 2011

JavaScript: IsNumeric, isNumber ยอมให้กรอกเฉพาะตัวเลขเท่านั้น

JavaScript มีฟังก์ชั่น IsNumeric() อยู่แล้ว สำหรับเช็คค่าว่าต้องเป็นตัวเลขเท่านั้น แต่มันไม่เวิร์คสำหรับบางเคส เช่น
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;

// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;

เราเขียนฟังก์ชั่นเองก็ได้ เช็คได้ถูกต้องกว่าต้นฉบับอีก


function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}

Saturday, December 4, 2010

ยินดีที่ได้รู้จัก

 ขากลับจากอินเดีย หลังจากเครื่องลงที่สนามบินสุวรรณภูมิ ก็เดินผ่านต.ม. รับกระเป๋าเสร็จ แล้วก็เดินผ่านศุลกากร เพื่อนผม 4 คนเดินนำไปก่อน ผมรั้งท้ายอยู่คนเดียว ทันใดนั้นมีศุลกากรหญิงท่านนึงเดินมาดักผม "ซวยแล้ว" ต้องโดนตรวจของแน่ แต่เราก็ไม่ได้มีของอะไรที่ผิดปกตินี่นา จะมาก็แต่ของฝากแบบเดียวกับที่พิงกี้ซื้อมาฝากพี่เป็ก ไม่ทันที่ผมจะคิดไปไกลกว่านั้น "ยูใช่ไหม" เขาถามผม โล่งเลย คนรู้จักกันแน่ แต่ใครหว่า "ใช่...ครับ" ไม่รู้จะครับดีหรือไม่ครับดี เพราะจำไม่ได้ว่ารู้จักกับเขาแบบไหน เป็นเพื่อน เป็นพี่ หรือเป็นน้อง "จำเราได้หรือเปล่า" อ้อ เพื่อนกันแน่ "เคยเรียน มอ.ด้วยกันตอนปี 1 ไง" ใครจะไปจำได้ เรียนด้วยกันปีเดียว แถมไม่ค่อยได้เข้าเรียน แต่ทำไมเขายังจำเราได้ "ยูไม่เปลี่ยนไปเลย" ... อุ๊ยเขิน แสดงว่าเราหน้าเด็ก จบมาตั้ง 10 ปีแล้ว คุยไปคุยมาก็ยังจำเขาไม่ได้อยู่ดี แต่ก็พอจะคุ้นๆบ้าง ... มั๊ง ก็อย่างที่บอก ไม่ค่อยได้เข้าเรียน วิชาที่เข้าเรียนบ่อยก็มีแต่ภาษาอังกฤษที่เรียนร่วมกับคณะวจก.(เพราะสาววจก.เน็กไทสีชมพูนั้นงามนัก^^) นอกนั้นก็เข้าตามเกณฑ์ขั้นต่ำที่ทำให้ยังมีสิทธิ์สอบอยู่ ศุลกากรคนนี้เขาเรียนมอ.แค่ปี 1 ปีเดียว แล้วก็ออกมาเรียนเอกชนที่กรุงเทพ

ตอนปี 1 คณะผมมีเพื่อนร่วมรุ่น 300 กว่าคน แต่เขายังจำผมได้ มีใครอีกบ้างนะที่เขาจำได้ มันเป็นเรื่องมหัศจรรย์จริงๆ กว่าเขาจะมายืนดักผมที่ด่านศุลกากร เขาต้องผ่านการรู้จักคนอื่นอีกกี่คน

แต่มันก็รู้สึกดีนะ เวลามีคนที่เราจำไม่ได้มาทัก นั่นแสดงว่าเรามีตัวตนบนโลกใบนี้ เป็นที่จดจำของใครบางคน มาทักทีก็มาพร้อมกับความทรงจำดีๆที่เคยมีร่วมกัน และความต้องการที่จะสานสัมพันธ์นั้นต่อ

อย่างที่เพลงมันบอก คือเรื่องมหัศจรรย์ ที่เราได้พบกัน บนโลกนี้มีคนตั้งไม่รู้กี่ล้านคน แล้วทำไม 2 คนในหลายล้านนั้นคือผมกับคุณที่รู้จักกัน มันเป็นเรื่องมหัศจรรย์จริงๆ เรื่องมหัศจรรย์ไม่ได้เกิดขึ้นง่ายๆ เราก็ต้องไม่ปล่อยให้มันผ่านไปง่ายๆ จงจดจำมันเอาไว้ให้นานที่สุด

ถึงเพื่อนๆทุกคน "ยินดีที่ได้รู้จักครับ"

Saturday, September 25, 2010

ไม่รู้ใครเป็นใคร

เรื่องแรก

"ตามไม่ทันพี่ ไปถามผู้หญิงคนนั้นเขาบอกไม่ใช่

ขณะที่ผมจ่ายเงินอยู่ที่เคาเตอร์เซเว่น พนักงานเซเว่นคนหนึ่งวิ่งกลับมาบอกพนักงานอีกคนที่อยู่ที่เคาเตอร์ เรื่องมีอยู่ว่ามีผู้หญิงคนหนึ่งซื้อของแล้วลืมเอาเงินทอน พนักงานขายแก่พรรษากว่าก็ใช้ให้พนักงานใหม่วิ่งเอาเงินทอนไปให้เขา แต่พนักงานคนนั้นตามไม่ทัน ช่วงเช้าเป็นเวลาที่มนุษย์เงินเดือนเดินไปเดินมาผ่านเซเว่นเยอะมาก ออกจากร้านไปก็ไม่รู้ว่าใครเป็นใครแล้ว เขาสะกิดถามผู้หญิงคนหนึ่งก็ไม่ใช่คนที่ลืมเงินทอน

คำว่า"แก่พรรษา" หมายถึงผู้ที่มีอายุงานเยอะกว่า อาวุโสกว่า ทำงานมาก่อน เลยมันจะข่มพนักงานใหม่ได้นิดๆถึงแม้ตำแหน่งจะเท่ากัน

ปกติพนักงานเซเว่นจะเก็บเงินทั้งหมดไว้ในลิ้นชักเครื่องคิดเงิน แต่เงินทอนที่ลูกค้าลืมไว้นั้นพนักงานตั้งไว้บนโต๊ะ คงจะรอลูกค้ากลับมาเอา

ถัดจากเซเว่นไปอีกประมาณ 100 เมตรเป็นคลองแสนแสบ

เรื่องที่ 2

"วันก่อนก็มีคนลืมตังทอน ให้แบงค์ 500 มาเราก็ทอนเศษไปก่อน พอได้เศษเขาก็ไปเลย อีก 400 ยังไม่ได้เอา พอหันหลังไปมันก็ปนกันไปหมด ไม่รู้ใครเป็นใคร" คนขายไก่ทอดเล่าให้ฟังหลังจากทอนเงินค่าข้าวหมกให้ผม

ที่ท่าเรืออโศกริมคลองแสนแสบ ด้านหลังท่าเรือมีร้านขายอาหารหลายร้าน หนึ่งในนั้นเป็นร้านนาดาข้าวหมกไก่ หาดใหญ่ (ข้าวเหนียวก็มี) โต๊ะตั้งอยู่ติดกับร้านข้าวไข่เจียว ร้านนี้เป็นไก่ทอดหาดใหญ่ของแท้ เพราะคนทอดเป็นคนหาดใหญ่ เปิดขายเฉพาะช่วงเช้าเท่านั้น ปกติจะขายทุกวันทำงาน ถ้าเดินมาจากท่าเรือก็จะผ่านร้านนี้อยู่แล้ว แต่ถ้าเดินมาจากรถไฟฟ้าใต้ดินวันไหนขายจะมีป้ายแขวนบอกไว้ตรงบันไดขึ้นสะพาน ถ้าไม่เห็นป้ายก็ไม่ต้องเดินมาดูที่ท่าเรือให้เสียเที่ยว แม้มันจะเพียงแค่ประมาณ 10 ก้าว

"ดีที่ตอนเที่ยงเขากลับมาเอา เขาก็กลัวว่าเราจะจำไม่ได้แล้วไม่ยอมให้เงินทอน เราก็บอกว่าไม่เป็นไร เรารู้อยู่ว่ามีคนลืมเงินทอน ถ้ามีคนกลับมาเอาเงินทอนแค่คนเดียวเราก็ไม่ขาดทุน"

เป็นวิธีคิดที่ดูซื่อๆ ตรงไปตรงมา และสบายใจ