Tag Archive update

SQL Server: update limit

เทสงานที่มีการบันทึกข้อมูลไว้ ถ้าจะทำอีกครั้งก็ต้อง update กลับไปเป็นเหมือนเดิม แต่เพราะว่าเงื่อนไขมันกว้างมาก ๆ เลยไปอัพเดตทั้ง table เลยมันช้าไป เปลืองทรัพยากร เลยหาวิธีอื่นดู

  • ROWCOUNT อย่างต้องการให้ update แค่ 100 รายการแรก
    • SET ROWCOUNT 100;
      UPDATE table_name
      SET colunm_name = …
      WHERE column_name = …
      SET ROWCOUNT 0;
  • TOP จะง่ายกว่าหน่อย
    • UPDATE TOP(100) table_name
      SET colunm_name = …
      WHERE column_name = …
  • CTE
    • ;WITH CTE AS
      (
      SELECT TOP 100 *
      FROM table_name
      ORDER BY colunm_name
      )
      UPDATE CTE SET colunm_name = …
  • Sub Query
    • UPDATE table_name
      SET column_name =…
      WHERE column_id IN (
      SELECT TOP 100 column_id
      FROM table_name
      WHERE column_name = 0
      )

เลือกเอาแบบที่ชอบได้เลยครับ ตัวที่ผมชอบที่สุดคือ ROWCOUNT เพราะว่าใช้ query จริง ๆ มาวางได้เลย

Windows: install error 0x800f0954

ถ้าลงโปรแกรมเก่า ๆ บางครั้งขะเจอ error 0x800f0954 ซึ่งสาเหตุคือ เราไปลงโปรแกรมที่เก่ากว่า version ปัจจุบัน อย่าง Poor Man’s T-SQL Formatter จะใช้ .net2 ที่เก่ามากหลายปีแล้ว ทำให้เจอ error code 0x800f0954

ก่อนอื่นโหลดตัวติดตั้ง .net 2 มาก่อน แต่เพราะว่ามันเก่ามากจนไม่สามารถหาตัวติดตั้งจาก microsoft ได้ ดังนั้นจะโหลดตัวติดตั้ง .Net 3.5 จาก Microsoft .NET Framework 3.5 ที่จะมี .NET Framework 2.0 และ .NET Framework 3.0 service pack ในตัวแทน

การเตรียมการติดตั้ง

  1. เปิดโปรแกรม regedit โดยไปที่เมนูของ windows พิมพ์ regedit.exe ในช่อง run หรือ search แล้ว enter
  2. เปิดคีย์ตามลำดับ HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU
  3. ดูที่ด้านขวาจะมี value ชื่อ UseWUServer เซ็ตค่าเป็น 0
  4. ปิด regedit
  5. restart windows หรือ restart service Windows Update

Cr. Error Code 0x800F0954 on Windows 10

slick: carousel / slideshow จาก ajax

ตัวอย่างการแก้ไข carousel หรือ slideshow โดย update slide จาก ajax

[code language=”html” title=”kenwheeler.slick/ajax.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>kenwheeler.slick: ajax update</title>
<link href="../vendor/components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="../vendor/kenwheeler/slick/slick/slick.css" rel="stylesheet" type="text/css" />
<link href="../vendor/kenwheeler/slick/slick/slick-theme.css" rel="stylesheet" type="text/css" />
<link href="theme.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="slideshowA"></div><br>
<select id="order_by">
<option value="asc">น้อยไปมาก</option>
<option value="desc">มากไปน้อย</option>
<option value="random">สุ่ม</option>
</select>
<script src="../vendor/components/jquery/jquery.min.js"></script>
<script src="../vendor/kenwheeler/slick/slick/slick.min.js"></script>
<script>
$(function() {

var order_by = $(‘#order_by’);
var slideshowA = $(‘#slideshowA’);

function getSliderSettings() {
return {
"autoplay": false,
"autoplaySpeed": 3000,
"centerMode": true,
"infinite": false,
"slidesToScroll": 4,
"slidesToShow": 4,
"speed": 300,
"variableWidth": true,
"zIndex": 2
}
}

function getSlideShow() {

$.ajax({
"data": {
"order_by": order_by.val(),
},
"success": function(data, textStatus, jqXHR) {

/* add items */
$.each(data.datas, function(index, value) {
slideshowA.append(‘<div><b>’ + index + ‘</b><img alt="’ + index + ‘" src="’ + value + ‘"><p>แสดง ‘ + index + ‘ จาก http://www.avatarsdb.com</p></div>’);
});

slideshowA.slick(‘unslick’); /* ONLY remove the classes and handlers added on initialize */
$(‘.my-slide’).remove(); /* Remove current slides elements, in case that you want to show new slides. */
slideshowA.slick(getSliderSettings()); /* Initialize the slick again */

alert(‘ทดลองดูครับ’);

},
"url": "ajax.php",
});

}

order_by.change(function() {
getSlideShow();
});

getSlideShow();
slideshowA.slick(getSliderSettings());
});
</script>
</body>

</html>[/code]

ไฟล์ที่ส่งข้อมูลกลับมาให้[code language=”php” title=”kenwheeler.slick/ajax.php”]<?php
$datas = [];

if (isset($_GET[‘order_by’])) {
$order_by = $_GET[‘order_by’];
} else {
$order_by = ‘asc’;
}

$datas[‘Acrobat’] = ‘http://www.avatarsdb.com/avatars/acrobat.gif’;
$datas[‘Cat Rain’] = ‘http://www.avatarsdb.com/avatars/cat_rain.gif’;
$datas[‘Dota Windranger’] = ‘http://www.avatarsdb.com/avatars/dota_windranger.jpg’;
$datas[‘Fighting Funny’] = ‘http://www.avatarsdb.com/avatars/fighting_funny.gif’;
$datas[‘Fire 01’] = ‘http://www.avatarsdb.com/avatars/fire_01.gif’;
$datas[‘German Shepherd Puppy’] = ‘http://www.avatarsdb.com/avatars/german_shepherd_puppy.jpg’;
$datas[‘Girl With Cigarette’] = ‘http://www.avatarsdb.com/avatars/girl_with_cigarette.jpg’;
$datas[‘Hidden Cat’] = ‘http://www.avatarsdb.com/avatars/hidden_cat.jpg’;
$datas[‘Im Fabulous’] = ‘http://www.avatarsdb.com/avatars/im_fabulous.jpg’;
$datas[‘One Direction’] = ‘http://www.avatarsdb.com/avatars/One_Direction.jpg’;
$datas[‘Panda Kiss’] = ‘http://www.avatarsdb.com/avatars/panda_kiss.gif’;
$datas[‘PC User’] = ‘http://www.avatarsdb.com/avatars/pc_user.gif’;
$datas[‘Riri Queen’] = ‘http://www.avatarsdb.com/avatars/riri_queen.gif’;
$datas[‘Tennessee’] = ‘http://www.avatarsdb.com/avatars/tennessee.jpg’;
$datas[‘Tuxedo M’] = ‘http://www.avatarsdb.com/avatars/Tuxedo_m.jpg’;
$datas[‘Tuxedo Mask’] = ‘http://www.avatarsdb.com/avatars/tuxedo_mask.jpg’;
$datas[‘Ugly Face’] = ‘http://www.avatarsdb.com/avatars/ugly_face.gif’;
$datas[‘Waifu’] = ‘http://www.avatarsdb.com/avatars/waifu.jpg’;
$datas[‘Wolf In The Snow’] = ‘http://www.avatarsdb.com/avatars/wolf_in_the_snow.jpg’;
$datas[‘Xerxes Break Kevin’] = ‘http://www.avatarsdb.com/avatars/xerxes_break_kevin.jpg’;

switch ($order_by) {
case ‘desc’:{krsort($datas);}
break;

case ‘random’:{
$keys = array_keys($datas);
shuffle($keys);
$random = [];
foreach ($keys as $key) {
$random[$key] = $datas[$key];
}
$datas = $random;
}break;

case ‘asc’:
default:
{ksort($datas);}
break;
}

header(‘Content-type: application/json; charset=utf-8’);
echo json_encode([
‘datas’ => $datas,
‘order_by’ => $order_by,
]);[/code]

code บางส่วนจะอยู่ในบทความ slick: สร้าง carousel / slideshow

Credit: Reinitialize Slick js after successful ajax call

update table อัตโนมัติ

สามารถให้ mysql หรือ MariaDB update หรือแก้ไขข้อมูลได้โดยอัตโนมัติทุกครั้งที่ insert, update และ delete ได้โดยใช้ trigger ช่วย จะยกตัวอย่างโดยสมมุติตาราง users โดยถ้า มีการเพิ่มข้อมูลมาใหม่ให้สุ่ม salt และ hash รหัสผ่านให้โดยอัตโนมัติ และเพื่อความปลอดภัยให้เปลี่ยน salt และ hash ใหม่ทุกครั้งที่ password เปลี่ยนไป ถ้าไม่เข้าใจว่า salt คืออะไร ขอเชิญอ่านจากเรื่อง login แบบปลอดภัย

สร้างตาราง users ก่อนโดยใช้[code language=”sql” title=”create table users”]CREATE TABLE `users` (
`user_id` int(11) NOT NULL,
`username` varchar(30) NOT NULL,
`password` char(32) NOT NULL,
`salt` char(5) NOT NULL,
`password_hash` char(32) NOT NULL,
`email` varchar(254) NOT NULL,
`date_create` datetime DEFAULT NULL,
`date_update` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`);

ALTER TABLE `users`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
[/code]

สร้าง trigger โดยใช้โครงสร้าง[code language=”text” title=”mysql trigger syntax”]DELIMITER $$
CREATE TRIGGER `ชื่อ trigger ` AFERT หรือ BEFORE INSERT หรือ UPDATE หรือ DELETE ON `ตาราง ` FOR EACH ROW BEGIN

SET NEW.`ชื่อฟิลย์ ` = ค่าใหม่;

END
$$
DELIMITER ;

[/code]

.OLD
ค่าใน record เดิมก่อน update
.NEW
ค่าใหม่ที่จะเข้ามา update เปลี่ยนค่าเดิม

trigger ของตาราง users ในแบบที่เราต้องการจะเขียนเป็น[code language=”sql” title=”automatic update by trigger”]–
— Triggers `users`

DELIMITER $$
CREATE TRIGGER `users_passwordhash_insert` BEFORE INSERT ON `users` FOR EACH ROW BEGIN
SET @string := ‘abcdefghijklmnopqrstuvwxyz0123456789’;
SET @i := 1;
SET @random := ”;

WHILE (@i <= 5) DO
SET @random := CONCAT(@random, SUBSTRING(@string, FLOOR(RAND() * 36 + 1), 1));
SET @i := @i + 1;
END WHILE;

SET NEW.`date_create` = NOW();
SET NEW.`salt` = @random;
SET NEW.`password_hash` = MD5(CONCAT(NEW.`password`, @random));
END
$$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER `users_passwordhash_update` BEFORE UPDATE ON `users` FOR EACH ROW BEGIN
SET @string := ‘abcdefghijklmnopqrstuvwxyz0123456789’;
SET @i := 1;
SET @random := ”;

WHILE (@i <= 5) DO
SET @random := CONCAT(@random, SUBSTRING(@string, FLOOR(RAND() * 36 + 1), 1));
SET @i := @i + 1;
END WHILE;

SET NEW.`date_update` = NOW();
SET NEW.`salt` = @random;
SET NEW.`password_hash` = MD5(CONCAT(NEW.`password`, @random));
END
$$
DELIMITER ;[/code]

ทดลองเพิ่ม และเปลี่ยนข้อมูลดูครับตัว salt และ password_hash จะต้องเปลี่ยนทุกครั้ง ในการใช้งานจริง ให้ลบฟิลย์ password ออกและแก้ trigger ใหม่ เพราะไม่ควรเก็บ password เป็นข้อความธรรมดา (plain text)

CRUD ใน laravel 5

บอกเลย CRUD (Create, read, update and delete generator) ใน laravel 5 หายากมากจน GII ของ YII ดูเทพขึ้นมาทันที ตัวที่พอจะเทียบได้ก็มี Laravel Generator

ติดตั้งโดย

  1. เพิ่ม package InfyOmLabs/laravel-generator ในไฟล์ composer.json[code language=”text” title=”composer.json”]
    "require": {

    "infyomlabs/adminlte-templates": "dev-master",
    "infyomlabs/generator-builder": "dev-master",
    "infyomlabs/laravel-generator": "dev-master",
    "infyomlabs/swagger-generator": "dev-master",
    "jlapp/swaggervel": "dev-master"
    "laravelcollective/html": "5.2.*"

    },
    [/code]
  2. run command[code language=”text” title=”command”]composer update[/code]
  3. เปิดไฟล์ \config\app.php เพิ่ม[code language=”php” title=”\config\app.php”]

    ‘providers’ => [

    \InfyOm\Generator\InfyOmGeneratorServiceProvider::class,
    \InfyOm\GeneratorBuilder\GeneratorBuilderServiceProvider::class,
    Collective\Html\HtmlServiceProvider::class,
    Laracasts\Flash\FlashServiceProvider::class,
    Prettus\Repository\Providers\RepositoryServiceProvider::class,

    ],

    ‘aliases’ => [

    ‘Flash’ => Laracasts\Flash\Flash::class,
    ‘Form’ => Collective\Html\FormFacade::class,
    ‘Html’ => Collective\Html\HtmlFacade::class,

    ],[/code]

  4. Publish ไฟล์ไปโฟลเดอร์ public โดย run command[code language=”text” title=”command”]php artisan vendor:publish
    php artisan infyom:publish[/code]
  5. Run routes Publish Command[code language=”text” title=”command”]php artisan infyom.publish:generator-builder[/code] จะเพิ่ม rute [code language=”php”]Route::get(‘generator_builder’, ‘\InfyOm\GeneratorBuilder\Controllers\[email protected]’);
    Route::get(‘field_template’, ‘\InfyOm\GeneratorBuilder\Controllers\[email protected]’);
    Route::post(‘generator_builder/generate’, ‘\InfyOm\GeneratorBuilder\Controllers\[email protected]’);[/code]
  6. Publish view โดย run command[code language=”text” title=”command”]php artisan infyom.publish:generator-builder –views[/code]
  7. เปิดไฟล์ \config\infyom\generator_builder.php แก้เป็น[code language=”php” title=”\config\infyom\generator_builder.php”]<?php

    return [

    ‘views’ => [

    ‘builder’ => ‘infyom.generator-builder.builder’,

    ‘field-template’ => ‘infyom.generator-builder.field-template’
    ]
    ];[/code]

  8. เปิดไฟล์ \config\infyom\laravel_generator.php แก้ ‘templates’ => ‘core-templates’, เป็น ‘templates’ => ‘adminlte-templates’,

ทดลองใช้

  1. ทดลองเรียกดู http://localhost/…/generator_builder
  2. แต่กรอกอะไรก็เจอ error Fail!result ลองจับ traffic ดูก็เห็นว่ามี error MethodNotAllowedHttpException in RouteCollection.php line 218: เปิดไฟล์ \resources\views\infyom\generator-builde\builder.blade.php บรรทัด 321 แก้ type: “POST” เป็น method: “POST”,

update ข้อมูลใน MySQL แบบหลายตาราง

กำลังทำ presashop ตัวใหม่อยู่ จำเป็นต้องใส่ต้อง copy feature จากภาษาหนึ่งไปอีกภาษาหนึ่งสำหรับ product 1,600 รายการ ถ้าเลือกใส่ใน backend ปกติถึงทำกัน 3 คนมือก็หงิกอยู่ดี (ยังไม่ต้องคิดว่าถ้าทำพลาดละ) และเพราะ prestashop เก็บข้อมูลโดยแยกแต่ละภาษา ออกไปอีกตารางจึ้งต้องเขียน sub query ตามแบบ
SQL Update column values using subquery
query ของผมเป็น
[code language=”sql”]
UPDATE `feature_value_lang` AS target INNER JOIN (
SELECT `id_feature_value` ,`value`FROM `feature_value_lang`
WHERE `id_lang` = 1
) AS source ON target.`id_feature_value` = source.`id_feature_value`
AND target.`id_lang` = 3
SET target.`value` = source.`value`
[/code]