Laravel JOIN SQLSTATE [23000] 问题:违反完整性约束:字段列表中的 1052 列“album_id”不明确

Posted

技术标签:

【中文标题】Laravel JOIN SQLSTATE [23000] 问题:违反完整性约束:字段列表中的 1052 列“album_id”不明确【英文标题】:Laravel JOIN Problem with SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'album_id' in field list is ambiguous 【发布时间】:2020-06-23 21:06:25 【问题描述】:

我参考了类似我的其他问题,但我无法弄清楚为什么在我的示例中出现错误。

我有 3 张桌子。 nn_album 、 nn_song 和数据透视表 nn_song_album_song

我的表 ID 名称是 nn_album.album_id 、 nn_song.song_id ,数据透视表有 id 作为主键和相同的列名“song_id”和“album_id”

我可以添加专辑,但是当我想在专辑中添加新歌时,保存功能出现此错误...

SQLSTATE[23000]:完整性约束违规:1052 字段列表中的列“album_id”不明确(SQL:从nn_album 内部连接nn_song_album_song 上选择album_id nn_album.album_id = nn_song_album_song .album_id 其中nn_song_album_song.song_id = 21)

我的歌曲模型

public function albums()

    return $this->belongsToMany('App\Albums', 'nn_song_album_song', 'song_id', 'album_id');

我的专辑模特

public function songs()

    return $this->belongsToMany('App\SongDetail', 'nn_song_album_song', 'song_id', 'album_id');

我的控制器保存功能

$albums = request('albums');

if ($song_id>0)

    $entry = SongDetail::where('song_id', $song_id)->firstOrfail();
    $entry->update($data);
    $entry->albums()->sync($albums);

else

    $entry = SongDetail::create($data);
    $entry->albums()->attach($albums);

我在管理员端的视图用于选择专辑输入(我可以选择多个专辑添加)

<div class="form-group form-float mainalbum" style="margin-bottom: 45px;border-bottom: solid 1px;">
    <div class="form-line">


        <select class="form-control show-tick" name="albums[]" id="albums" data-live-search="true" >

            @foreach($albums as $album)
                @if($album->album_id != 1)<option value=" $album->album_id "  collect(old('albums', $album))->contains($album->album_id) ? 'selected': '' >
                     $album->album_name </option>@endif
            @endforeach


        </select>
        <select class="albums2" name="albums2[]" id="albums2" multiple>
            @foreach($albums as $album)
                @if($album->album_id != 1)<option value=" $album->album_id "  collect(old('albums', $album))->contains($album->album_id) ? 'selected': '' >
                     $album->album_name </option>@endif
            @endforeach
        </select>
    </div>

</div>

你知道这里发生了什么吗?我的错是什么?如果你和我分享你的想法,我很感激你。

谢谢。

【问题讨论】:

那么 sql 错误消息向您指出的是,album_id 存在于两个表中,但您选择的 album_id 没有指定您想要的,因此它是模棱两可的 感谢 Patrick 的回复,但是我如何在 Laravel 上的模型中编写这个 sql?你有什么想法吗? 所提供的答案是否有帮助?如果您有这样做的声誉,您应该用 ▲ 所有答案 支持。然后,您应该标记接受 ✓ 最能回答您问题的一个答案。 This will mark the question as "closed," and give you some reputation on the site。如果没有一个答案令人满意,请向 cmets 提供反馈,或编辑您的问题以澄清问题。 【参考方案1】:

那么 sql 错误消息指出的是,两个表中都存在album_id,但是您选择了album_id 而没有指定您想要的那个,因此它是模棱两可的

您可以通过指定行上的确切列来解决此问题

return $this->belongsToMany('App\Albums', 'nn_song_album_song', 'song_id', 'album_id');

把它改成

return $this->belongsToMany('App\Albums', 'nn_song_album_song', 'nn_song_album_song.song_id', 'nn_song_album_song.album_id');

我不是 100% 支持这个解决方案,因为这不是我最熟悉的语法,但为输出参数指定表应该可以解决问题。您可能需要将寿应用于这两个模型。实际的解决方案可能是这种情况的变体,但您将通过使用此处和其他答案中提到的点语法更具体地为查询中的字段指定表名来解决此问题。

【讨论】:

【参考方案2】:

好吧,通过根据 Laravel 约定命名所有内容,您确实使事情变得比您需要的要复杂得多。如果按预期设置,您将拥有名为 AlbumSong 的模型,存储在数据库表 albumssongs 中,并带有一个名为 album_song 的数据透视表。那时事情会容易得多。

但如果有一个reads the documentation,则可以解决这些约定:

如前所述,为了确定关系的连接表的表名,Eloquent 会按字母顺序连接两个相关的模型名。但是,您可以随意覆盖此约定。您可以通过将第二个参数传递给 belongsToMany 方法来实现。

除了自定义连接表的名称外,您还可以通过将附加参数传递给belongsToMany 方法来自定义表上键的列名。 第三个​​参数是您要定义关系的模型的外键名称,而第四个参数是您要加入的模型的外键名称。

所以,修正你的论点,我们得到:

class SongDetail extends Model

    public function albums()
    
        return $this->belongsToMany('App\Albums', 'nn_song_album_song', 'song_id', 'album_id');
    


class Albums extends Model

    public function songs()
    
        return $this->belongsToMany('App\SongDetail', 'nn_song_album_song', 'album_id', 'song_id');
    

应该正确定义关系。您的控制器再次违反约定,因为 Laravel 资源控制器通常定义单独的存储和更新方法。但我可以提出一个建议来清理您显示的代码:

$albums = request('albums');

try 
    $entry = SongDetail::findOrFail($song_id);
    $entry->update($data);
 catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) 
    $entry = SongDetail::create($data);

$entry->albums()->sync($albums);

在您看来,如果您想传递一个值数组,您需要在 &lt;select&gt; 元素上指定 multiple

【讨论】:

【参考方案3】:

当您加入两个表时,它也会加入列名。您必须描述要从哪个表中获取album_id 列。例如nn_album.album_idnn_song_album_song.album_id

您的 sql 查询必须如下所示:select nn_album.album_id from nn_album inner join nn_song_album_song on nn_album.album_id = nn_song_album_song.album_id where nn_song_album_song.song_id = 21

【讨论】:

感谢 Ramünas 的回复,但我如何在 Laravel 上的模型中编写此 sql?你有什么想法吗?

以上是关于Laravel JOIN SQLSTATE [23000] 问题:违反完整性约束:字段列表中的 1052 列“album_id”不明确的主要内容,如果未能解决你的问题,请参考以下文章

SQLSTATE [42S22]:找不到列:1054 未知列 - Laravel

SQLSTATE[HY000] [1049] 未知数据库 'laravel'

SQLSTATE [23502]:非空违规:7 错误 - laravel

Laravel:SQLSTATE [28000] [1045] 用户 'homestead'@'localhost' 的访问被拒绝

Laravel:SQLSTATE [HY000] [2002] 连接被拒绝

SQLSTATE [23000]:完整性约束违规:1048 laravel 5.7