我正在使用 Laravel 8.40 并尝试将我的 WebApp 迁移到
SQL Server 2008 R2 SP1
在 MySQL 上一切正常,但在我迁移数据库(使用普通 SQL 命令)后,在 IIS 7.5、PHP 7.4、MS SQL Server 2008 上尝试我的应用程序时,我在尝试注册用户时收到此错误
SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Implicit conversion from data type nvarchar to varbinary is not allowed. Use the CONVERT function to run this query. (SQL: insert into [users] ([username], [email], [password]) values (wolf, [email protected], $2y$10$1b.fjIEbBXgB30J8E6QIsuroXwXqx.WezBIodnnqOgszUJ92LvGgO))
我的用户模型(User.php)看起来像这样
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use App\Casts\uuid;
use Illuminate\Support\Facades\DB;
/**
* @OA\Schema(
* title="User",
* description="User model",
* @OA\Xml(
* name="User"
* )
* )
*/
class User extends Authenticatable
{
use Notifiable;
protected $primaryKey = 'UUID';
public $incrementing = false;
public $timestamps = false;
protected $casts = [
'UUID' => uuid::class,
'password' => 'string',
'created_at' => 'timestamp',
'updated_at' => 'timestamp'
];
protected $dates = [
'created_at',
'updated_at'
];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* @OA\Property(
* title="username",
* description="username",
* example="veso266"
* )
*
* @var string
*/
public $UUID;
/**
* @OA\Property(
* title="username",
* description="username",
* example="wolf"
* )
*
* @var string
*/
public $username;
/**
* @OA\Property(
* title="email",
* description="E-Mail Address",
* example="[email protected]"
* )
*
* @var string
*/
public $email;
/**
* @OA\Property(
* title="email",
* description="E-Mail Verificytion date",
* example="null"
* )
*
* @var timestamp
*/
public $email_verified_at;
/**
* @OA\Property(
* title="password",
* description="User Password",
* example="$2y$10$HPfubOU.XX/OptS3sAH73OC3iz6BLsJvIKFyFaoLMt3.."
* )
*
* @var string
*/
public $password;
/**
* @OA\Property(
* title="remember_tokem",
* description="If we shall remember the user token",
* example="null"
* )
*
* @var string
*/
public $remember_token;
/**
* @OA\Property(
* title="created_at",
* description="User Creation Date",
* example="1621804555"
* )
*
* @var timestamp
*/
public $created_at;
/**
* @OA\Property(
* title="updated_at",
* description="User Update Date",
* example="1621804600"
* )
*
* @var timestamp
*/
public $updated_at;
public function generateToken()
{
$this->api_token = Str::random(60);
$this->save();
return $this->api_token;
}
public static function status()
{
$sql = DB::select("SELECT
users.UUID,
users.username,
users.email,
users.api_token
FROM users;");
return $sql;
}
}
我的演员\uuid.php
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class uuid implements CastsAttributes
{
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return mixed
*/
public function get($model, $key, $value, $attributes)
{
$hex = bin2hex($value);
return substr($hex, 0,8) .'-'. substr($hex, 8,4) .'-'. substr($hex, 12,4) .'-'. substr($hex, 16,4) .'-'. substr($hex, 20,12);
}
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return mixed
*/
public function set($model, $key, $value, $attributes)
{
return hex2bin($value);
}
}
我的RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use MyLibs\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'username' => ['required', 'string', 'max:255', 'unique:users', 'regex:/^\S*$/u'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
public function register(Request $request)
{
// Here the request is validated. The validator method is located
// inside the RegisterController, and makes sure the name, email
// password and password_confirmation fields are required.
$this->validator($request->all())->validate();
// A Registered event is created and will trigger any relevant
// observers, such as sending a confirmation email or any
// code that needs to be run as soon as the user is created.
event(new Registered($user = $this->create($request->all())));
// After the user is created, he's logged in.
$this->guard()->login($user);
// And finally this is the hook that we want. If there is no
// registered() method or it returns null, redirect him to
// some other URL. In our case, we just need to implement
// that method to return the correct response.
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
protected function registered(Request $request, $user)
{
$user->generateToken();
return response()->json(['data' => $user->toArray()], 201);
}
}
这是我在数据库中为用户提供的表格
IF OBJECT_ID('dbo.users', 'U') IS NOT NULL
DROP TABLE dbo.users;
GO
-- Create the `users` table
CREATE TABLE dbo.users (
UUID UNIQUEIDENTIFIER NOT NULL,
username NVARCHAR(10) NOT NULL,
email NVARCHAR(255) NOT NULL,
email_verified_at DATETIME NULL,
password VARBINARY(60) NOT NULL, -- SHA512 Hash stored as binary
api_token NVARCHAR(60) NULL,
remember_token NVARCHAR(100) NULL,
created_at DATETIME NULL DEFAULT ('0001-01-01T00:00:00'),
updated_at DATETIME NULL DEFAULT ('0001-01-01T00:00:00'),
CONSTRAINT PK_users PRIMARY KEY (UUID),
CONSTRAINT UQ_users_email UNIQUE (email),
CONSTRAINT UQ_users_api_token UNIQUE (api_token)
);
GO
-- Triggers for the `users` table
-- Trigger to generate UUID on insert
CREATE TRIGGER trg_generate_UUID
ON dbo.users
INSTEAD OF INSERT
AS
BEGIN
DECLARE @newUUID UNIQUEIDENTIFIER
SET @newUUID = NEWID() -- Generates a unique UUID
INSERT INTO dbo.users (UUID, username, email, email_verified_at, password, api_token, remember_token, created_at, updated_at)
SELECT @newUUID, username, email, email_verified_at, password, api_token, remember_token, COALESCE(created_at, GETDATE()), COALESCE(updated_at, GETDATE())
FROM inserted;
END;
GO
-- Trigger to set created_at and updated_at on insert
CREATE TRIGGER trg_user_create
ON dbo.users
AFTER INSERT
AS
BEGIN
UPDATE dbo.users
SET created_at = GETDATE(),
updated_at = GETDATE()
WHERE UUID IN (SELECT UUID FROM inserted);
END;
GO
-- Trigger to set updated_at on update
CREATE TRIGGER trg_user_update
ON dbo.users
AFTER UPDATE
AS
BEGIN
UPDATE dbo.users
SET updated_at = GETDATE()
WHERE UUID IN (SELECT UUID FROM inserted);
END;
GO
所有其他答案都是这样的: 不允许从数据类型 varchar(max) 到 varbinary(max) 的隐式转换。使用 CONVERT 函数运行此查询
正在使用原始 SQL 语句,而我没有(我使用 ORM),所以甚至不确定在哪里放置 CONVERT 语句?
我能做什么?