தகவல் தளம்
தகவல்தளத்தினுள் தவறான தகவல் சேர்ந்துவிடாமல் இருக்க database constraints உதவுகிறது. தகவல் சீர்மைக்கு constraint இன்றியமையாதது. இந்த கன்ஸ்ட்ரைண்டில் பல வகைகள் உள்ளன. உதாரணமாக default value constraint (காலியான தகவல் இருப்பதை அனுமதிக்க/மறுக்க), foreign key constraint (மற்ற டேபிள்களுடன் எந்த விட தொடர்பும் இல்லாத தகவல்களை நிராகரிக்க), check constraint (நாம் குறிப்பிடும் சில நிபந்தனைகளுக்கு உட்படும் தகவலை மட்டும் அனுமதிக்க) போன்றவை.
`Check constraint கொஞ்சம் flexible ஆனது. நாம் விரும்பும் data validation எல்லாவற்றையும் ஒவ்வொரு fieldக்கும் வைக்கலாம்.
எடுத்துக்காட்டாக, ஒரு தமிழ் வலைப்பதிவு மென்பொருளை உருவாக்குவதாக வைத்துக்கொள்வோம். இந்த மென்பொருளில் ஒரு கண்டிஷன் வைக்கலாம். வலைப்பதிவின் தலைப்பு கண்டிப்பாகத் தமிழில்தான் இருக்கவேண்டும். எதற்கு இப்படி ஒரு வெட்டிவேலை என்று நினைக்கத்தோன்ற்கிறதா? நல்ல கேள்வி. அத்ற்கு விடை இந்தப்பதிவின் கடைசியில் சொல்கிறேன்.
அப்ளிகேஷன் அளவில் இதற்கு ஒரு நிபந்தனையை அமைத்து தகவல் உள்ளீட்டு நிலையிலேயே ஆங்கில எழுத்துக்கள் உள்ள தலைப்பைக்...
ஒரு டேபிளிலுள்ள தகவலை இற்றைப்படுத்தவும், புதுத்தகவலை உள்ளிடவும் எஸ்க்யூஎல் சர்வரில் ஸ்டோர்ட் ப்ரோசீஜர் எழுதும்போது டேபிளில் உள்ள காலம்களுக்குத் தகுந்தவாறு நிறைய காரணிகளை வரையறுக்க வேண்டியிருக்கும். தூய தமிழில் சொல்வதென்றால், ஸ்டோர்ட் ப்ரோசீஜரில் இன்ஸர்ட்/அப்டேட் ஸ்டேட்மெண்ட்டில் பயன்படுத்த, நிறைய பாராமீட்டர்களை தட்டச்சடிக்க வேண்டியிருக்கும். டேபிள் மிகவும் பெரியதாக, அதிகமான காலம்கள் கொண்டதாக இருந்தால் இதற்கு நிறைய நேரமெடுக்கும். அதனால், ஒரு சிறு உதவிசெயல்நிரலை முயற்சித்தேன். இந்த நிரலிலுள்ள தகவல்தளத்தின் பெயரையும், டேபிளின் பெயரையும் தேவைக்கேற்ப மாற்றி F5 தட்டவும். CREATE PROCEDURE, INSERT, UPDATE statements எல்லாம் போட்டு ஓரளவிற்கு வேலையைக்குறைக்கும் ஸ்டோர்ட் ப்ரோசிஜர் டெம்ப்ளேட் கிடைக்கும். என்ன கொடுமை சரவணா இது. மேனேஜ்மெண்ட் ஸ்டூடியோவில் மெசேஜ் விண்டோ யூனிகோடுக்கு இசைவானதாக இல்லை!!! அதனால் எழுத்துக்கூட்டி, ஆங்கிலத்திலேயே வேலிடேஷன் பிழைச்செய்திகள்: 1:...
சில நேரங்களில், எஸ்க்யூஎல் சர்வரிலிருந்து தகவலை எடுக்கும்பொழுது, தொடர்ச்சியான ஒரு எண்ணும் வரவழைக்கவேண்டிய தேவை இருக்கலாம். உதாரணமாக, கீழ்க்கண்டவாறு ஒரு ஒரு வினவல் இருப்பதாக வைத்துக்கொள்வோம்:
select * from table1
அதன் விடை இப்படி இருப்பதாக இருக்கிறது என்று வைத்துக்கொள்வோம்:
col1
col2
col3
...
ஒரு கணிப்பொறியில் உள்ள டேட்டாபேசை மற்றொரு கணிப்பொறிக்கு மாற்ற/பிரதி எடுக்க பல வழிகள் உள்ளன. அவற்றில் ஒன்று டேட்டாபேசின் mdb மற்றும் log கோப்புக்களை நேரடியாக இரண்டாவது கணினியில் உள்ள எஸ்க்யூஎல் சர்வருக்கு இணைப்பது. இதை மேனேஜ்மெண்ட் ஸ்டூடியோ துணைகொண்டு இடைமுகப்பு வழியாகவோ, அல்லது கீழ்க்காணும் வினவற்தொகுப்பின் உதவியுடனோ செய்யலாம்:
CREATE DATABASE [thendral] ON
( FILENAME = N'drive:\path\dbname_Data.MDF' ),
( FILENAME = N'drive:\path\dbname_Log.LDF' )
FOR ATTACH
GO
if not exists (select name from master.sys.databases where name = N'dbname' and SUSER_SNAME(sd.owner_sid) = SUSER_SNAME() ) EXEC [dbname].dbo.sp_changedbowner @loginame=N'machinename\adminuser', @map=false
இவ்வாறு செய்யும் பொழுது, சில சமயம் டேட்டாபேசை இணைக்க முடியாமல் கீழ்க்கண்ட பிழைச்செய்தி வரக்கூடும்:
Msg 5118, Level 16, State 1, Line 1
The file "drive\path\dbname_Data.MDF" is compressed but does not reside in a read-only database or filegroup. The file...
செந்தில்: அண்ணே, எனக்கு ஒரு சந்தேகம்ணே...
கௌண்டமணி: டெக்னிக்கலா எதாவது சந்தேகம்னா, கேளு. வேற ஏதாவது கோக்கு மாக்கா கேட்ட, அப்பறம் தலையயும் ஓம்மூஞ்சி மாதிரி மாத்திடுவேண்டா client feedback தலையா...
செந்தில்: அதில்லண்ணே... ASP.NETல இந்த timeout error எரர், timeout எரர்ன்னு ஒன்னு வருதே, அத எப்படின்னே சரி பண்றது?
கௌண்டமணி: அடேய் க்ளைன்ட் வாயா... இப்படி பொத்தாம்பொதுவா user மாதிரி எரர் ரிப்போர்ட் பண்ணினா எப்படிடா புரியும்? என்ன எரர்ன்னு முழுசா சொல்லுடா...
செந்தில்: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
டி. ராஜேந்தர்: யம்மா தங்கச்சி, எர்ரர் உருவாச்சி. வீட்டுக்கு நேரமாச்சி, வயிறும் தடுத்தாச்சி.
ஒனக்கு நெனவிருக்காம்மா... சின்ன வயசுல எஸ்க்யூஎல் சர்வரோட கனெக்ட் பண்ணி வெளயாடும்போது, டைம் ஔட் எர்ரர் வருது டைம் ஔட் எர்ரர் வருதுன்னு நீ சொல்லுவ, டைம் ஔட் value...
எக்சல் கோப்புகளை எக்சல் ஆப்ஜக்ட் பயன்படுத்தாமலேயே வெறும் OleDbConnectionனை மட்டும் வைத்துக்கொண்டே டாட்நெட் தொழில்நுட்பம் பயன்படுத்த முடியும், கீழ்க்கண்டவாறு:
OleDbConnection xlConn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\filename.xls;Extended Properties='Excel 8.0;'");
இதிலுள்ள ஒவ்வொரு சீட்டையும் ஒரு டேபிலாகப் படிக்கலாம்.
பிறகு டேபிளில் உள்ள வரிசைகளைப் படிக்க "select * from [sheet1$]" என்று அடாப்டரிலோ அல்லது கமாண்ட் ஆப்ஜக்டிலோ வினவளைக் கொடுக்கவேண்டியதுதான். இதில் ஒரு சிறிய பிரச்சனை என்னவென்றால் டேட்டாடைப்பை OleDbConnection புரிந்துகொள்ளும் விதம்தான். உதாரணமாக, எண்கள் மட்டும் இருக்கவேண்டிய ஒரு காலத்தில் (column) ஒரு எழுத்துச்சரத் தகவல் இருந்தது என்றால் அந்த தகவலை எடுத்துக்கொள்ளாமல் வெறும் null என்று அந்த இடத்தில் எடுத்துக்கொள்ளும். இதைத் தவிர்க்க, தகவல்தொடர்ப்புச் சரத்தில், IMEX=1 என்று சேர்த்துத் தரவேண்டும், கீழ்க்கண்டவாறு:
OleDbConnection xlConn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\filename.xls;Extended Properties='Excel 8.0;IMEX=1'");
பகிர்வு நிலையில் இருக்கும் வெப் சர்வரில் (shared hosting) நிறுவப்பட்ட இணையப் பயன்பாடுகளில,் ஸ்டோர்ட் ப்ரோசீஜரை அழைக்கும்பொழுது அடுத்துள்ள வரியினைப் போன்ற பிழைச்செய்தி சில நேரம் வரலாம்:
EXECUTE permission denied on object 'storedprocedure_name்' database 'டேட்டாபேஸ்' owner 'குப்புசாமி'
SQL Script கோப்பு அல்லது அப்படியே காப்பி/பேஸ்ட் செய்யப்பட்ட ஸ்டோர்ட் ப்ரோசிஜர் வரிகளைப் பயன்படுத்தி உருவாக்கும்பொழுது, குறிப்பிட்ட ச்டோர்ட் ப்ரோசிஜருக்கான சொந்தக்காரர் dbo என்றே அமைந்து விடும் நிலை ஏற்படுகிறது. அதாவது, dbo.storedprocedure_name என்ற முழுப்பெயரில். உரிமைகள் வரையறுக்கப்பட்ட ஒரு பயனர்க்கணக்கிலிருந்து இயக்கப்படும்போது, இவ்விதமான ஸ்டோர்ட் ப்ரோசிஜர் (மற்றும் எல்லா விதமான டேட்டாபேஸ் ஆப்ஜக்ட்களுமே) மிகவும் பாதுகாப்பாக இருக்கிறது. எனினும், அப்படிப்பட்ட பயனர்க்கணக்குக்கு இந்த ஸ்டோர்ட் ப்ரோசிஜரை அழைக்க, இயக்குவுரிமை எனப்படும் execute permission இருக்க வேண்டும். இல்லையென்றால் அப்படிப்பட்ட பயனர்க்கணக்கினால் ஒரு பெரிய பயனும் இல்லை.
வெப் சர்வர் நிறுவன உதவியாளர்களிடம் இப்படிப்பட்ட பிழைச்செய்தியைப் பற்றி முறையிட்டால், "ஆப்ஜக்ட் ஓனரை...
எஸ்க்யூஎல் சர்வரில் char, varchar என்று இரண்டு வெவ்வேறு மாறிலி வகைகள், ஒரே நோக்கத்திற்காக இருக்கின்றன.
ஆரம்பக்கால தகவல்தள வடிவமைப்பாளருக்கு இவ்விரண்டில் சிறிய எழுத்துச் சரங்களை(small strings)த் தேக்கி வைக்க எதைத் தேர்ந்தெடுப்பது என்பதில் சில நேரங்களில் குழப்பம் வரலாம். பெரும்பாலும் varcharதான் தேர்ந்தெடுக்கப் படுகிறது. ஒப்பீட்டளவில், varcharன் பொருளான "மாற்றி அமைத்துக்கொள்ளும் மாறிலி வகை" (variable character) என்ற பண்பின் ஈர்ப்பு இதற்குக் காரணமாக இருக்கலாமோ என்று தோன்றுகிறது.
தத்தமது தகவலைச் சேமிக்கும் முறை மற்றும் வினவலுக்குத் தகவலைத் திரட்டி வழங்கும் முறைகளால் char மற்றும் varchar மாறிலிகள் வேறுபடுகின்றன. இவற்றுக்கு இடையேயான அடிப்படை வேற்றுமை என்று பார்த்தால், மிகவும் பிரசித்தமான, சரங்களைப் பதியும் விதம் எனலாம். அதாவது, char வகையில் தேக்கி வைக்கப்படும் தகவலானது, அந்த fieldன் வரையறுக்கப்பட்ட நீளத்தைவிடச் சிறியதாயினும் கூட வரையறுக்கப்பட்ட முழு இடத்தையும் எடுத்துக்கொள்ளும். varchar fieldல் சேமிக்கப்பட்ட தகவல், அதன் நீளத்திற்கு உண்டான இடத்தை மட்டுமே...
டேட்டாபேசுடன் தனிமையில் ஆர அமர உட்கார்ந்து பேசவோ, ஒரேயடியாக அழிக்கவோ முயல நினைத்தால், சில நேரங்களில் இயலாமல் போகலாம். உதாரணத்திற்கு,DROP DATABAES <dbname>என்ற வினவலுக்கு Cannot drop the database <dbname> because it is currently in use.என்ற பிழைச்செய்தி வரலாம்.
இப்படிப்பட்ட நேரங்களில் நாம் எண்ணியதை முடிக்க ஒரே வழி, தகவல் தளக்கோப்புக்கும் வெளி உலகுக்குமான தொடர்பை ஒட்டுமொத்தமாகத் துண்டிப்பதுதான்.
ALTER DATABASE <dbname> SET SINGLE_USER
என்று வினவல் இதற்கு பயன்படும். அந்த கணத்தில் தொடர்பில் இருக்கும் பயனர்கள் தத்தமது நிலுவையில் இருக்கும் செயல்களை முடித்துக்கொண்ட பிறகு, <dbname> என்ற பெயருடைய டேட்டாபேஸ் ஒருமைப் பயனர் நிலைக்கு வந்துவிடும். ஒரு வலைத்தளம் அல்லது பலர் பயன்படுத்தும் மென்பொருளுக்கான தகவல்தளத்திற்கு இந்த வினவலே சரியாக இருக்கும்.
என்ன ஆனாலும் சரி, டேட்டாபேசை அழித்தே தீருவது என்ற முடிவுக்கு வந்துவிட்டால்,
ALTER DATABASE
<dbname>
SET SINGLE_USER
WITH ROLLBACK immediate
என்று வினவினால் போதும். அந்த நொடியே எல்லா பயனருடைய...
இன்று காலை நான் பணியகம் வந்ததும் ஒரு மென்பொருள் இயங்க மறுத்து சண்டித்தனம் செய்தது. மென்பொருளின் log file பார்த்ததும் SQL Server ப்ரச்சனை என்று புரிந்தது.
கடைசியில் பார்த்தால், அட ஆமாம். SQL Server அமைதியாக உறங்கிக் கொண்டிருந்தது. Administrative Tools->Services சென்று start பண்ணினால்
The MSSQLSERVER service on Local Computer started and then stopped. Som eservices stop automatically if they have no work to do, for example, the Performance Logs and Alerts service.
என்று ஒரே ஒரு தகவல்பெட்டி மட்டும் காண்பித்துவிட்டு மடக்கென்று படுத்துவிட்டது.
அப்புறமென்ன, Event Log தான் ஒரே வழி. நேரே Event viewer->Applicationக்கு ஒரு சுற்றுப்பயணம் மேற்கொண்டு பார்க்கும்படியான நிலமை. அங்கே ஒரு விஷயம் கிடைத்தது. ஒரு error log.
17204 :FCB::Open failed: Could not open device C:\Program Files\Microsoft SQL Server\MSSQL\Data\<dbname>_Log.LDF for...
ஒவ்வொரு ப்ரச்சனைக்கும் பல வழிகளில் தீர்வு காணலாம். சிலவை மிகச்சில நிரல்வரிகளே கொண்டிருக்கும். சில பேர் எழுதும் நிரல்களில் தேவையின்றி நிறைய நிரல்வரிகள் இருக்கும்.
உதாரணமாக, கீழ்க்கண்ட நிரல்வரிகளை Query Analyzerல போட்டு F5 விசையை அழுத்தி Messages சாளரத்தில் பாருங்கள்.
use masterdeclare @DbName varchar(1000)declare @DbFileName varchar(1000)declare cursormasters cursor for select name,filename from Sysdatabasesopen cursormastersfetch next from cursormasters into @DbName,@DbFileNamewhile @@fetch_status=0beginif(not @DbName='master')beginprint 'Deleting database file ''' + @DbFileName + '.MDF''.'print 'Deleting database file ''' + replace(@DbFileName,'.MDF','_LOG.LDF') + '''.'endelseprint 'Could not delete master database...'fetch next from cursormasters into @DbName,@DbFileNameendclose cursormastersdeallocate cursormasters
ஒன்றும் அதிர்ச்சியடையவில்லை தானே? இதே outputஐ வரவழைக்க வேறு சில சுலபமான வழிகளும் இருக்கிறதுதான்.
ஆனால், இரண்டு print statement கொடுப்பதற்குப் பதிலாக ஒரே ஒரு வரியிலேயே அந்த output வரவழைக்கலாமாமே? அது எப்படி என்று எனக்குத்...